diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8753dca7f9..899278bbd3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,6 +20,7 @@ jobs: - run: | npm i echo "//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}" >> $HOME/.npmrc 2> /dev/null + npm run tsc:build npm run lerna:publish env: NODE_AUTH_TOKEN: ${{secrets.npm_token}} diff --git a/.gitignore b/.gitignore index 124586563b..684ff00936 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ yarn.lock .DS_Store docs-vuepress/.vuepress/dist elevate/ +packages/webpack-plugin/lib/runtime/components/react/dist/ \ No newline at end of file diff --git a/examples/mpx-webview/H5/webviewbridge.min.js b/examples/mpx-webview/H5/webviewbridge.min.js index d31f3b9b96..b94c23c965 100644 --- a/examples/mpx-webview/H5/webviewbridge.min.js +++ b/examples/mpx-webview/H5/webviewbridge.min.js @@ -1,11 +1,6 @@ /** - * mpxjs webview bridge v2.9.44 + * mpxjs webview bridge v2.9.53 * (c) 2024 @mpxjs team * @license Apache */ -/** - * mpxjs webview bridge v2.9.44 - * (c) 2024 @mpxjs team - * @license Apache - */ -var e,t;e=this,t=function(){"use strict";function e(e,t,o){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var o=e[Symbol.toPrimitive];if(void 0!==o){var n=o.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function t(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}var o,n,a,r,i=function(o){for(var n=1;n-1&&u.indexOf("MiniProgram")>-1?c="my":u.toLowerCase().indexOf("miniprogram")>-1?c=u.indexOf("QQ")>-1?"qq":"wx":u.indexOf("swan/")>-1?c="swan":u.indexOf("toutiao")>-1?c="tt":(c="web",window.addEventListener("message",(function(e){var t=e.data,o=t.callbackId,n=t.error,a=t.result;void 0!==o&&d[o]&&(n?d[o](n):d[o](null,a),delete d[o])}),!1));var g=!1;function l(e){g?e():o.then((function(){g=!0,e()}))}var w={config:function(e){"wx"===c?l((function(){window.wx&&window.wx.config(e)})):console.warn("\u975e\u5fae\u4fe1\u73af\u5883\u4e0d\u9700\u8981\u914d\u7f6econfig")}};function f(e){if("[object Object]"!==Object.prototype.toString.call(e))return e;var t={};for(var o in e)"function"!=typeof e[o]&&(t[o]=e[o]);return t}function m(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("getEnv"!==e){var o=++s;d[o]=function(e,n){e?(t.fail&&t.fail(e),t.complete&&t.complete(e)):(t.success&&t.success(n),t.complete&&t.complete(n)),delete d[o]};var n={type:e,callbackId:s,payload:f(t)};void 0!==p&&(n.clientUid=p),window.parent.postMessage&&window.parent.postMessage(n,"*")}else t({webapp:!0})}var v=function(){var e={wx:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","postMessage","getEnv"]},tt:{keyName:"miniProgram",api:["redirectTo","navigateTo","switchTab","reLaunch","navigateBack","setSwipeBackModeSync","postMessage","getEnv","checkJsApi","chooseImage","compressImage","previewImage","uploadFile","getNetworkType","openLocation","getLocation"]},swan:{keyName:"webView",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]},qq:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]}}[c]||{},t={wx:["checkJSApi","chooseImage","previewImage","uploadImage","downloadImage","getLocalImgData","startRecord","stopRecord","onVoiceRecordEnd","playVoice","pauseVoice","stopVoice","onVoicePlayEnd","uploadVoice","downloadVoice","translateVoice","getNetworkType","openLocation","getLocation","startSearchBeacons","stopSearchBeacons","onSearchBeacons","scanQRCode","chooseCard","addCard","openCard"],my:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","chooseImage","previewImage","getLocation","openLocation","alert","showLoading","hideLoading","getNetworkType","startShare","tradePay","postMessage","onMessage","getEnv"],swan:["makePhoneCall","setClipboardData","getNetworkType","openLocation","getLocation","chooseLocation","chooseImage","previewImage","openShare","navigateToSmartProgram"],web:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage","getLoadError","getLocation"],tt:[]}[c]||[];(e.api||[]).forEach((function(t){w[t]=function(){for(var o=arguments.length,n=new Array(o),a=0;a1&&void 0!==arguments[1]?arguments[1]:{},o=t.time,n=void 0===o?5e3:o,a=t.crossOrigin,r=void 0!==a&&a;function i(){return new Promise((function(t,o){var n=document.createElement("script");n.type="text/javascript",n.async="async",r&&(n.crossOrigin="anonymous"),n.onload=n.onreadystatechange=function(){this.readyState&&!/^(loaded|complete)$/.test(this.readyState)||(t(),n.onload=n.onreadystatechange=null)},n.onerror=function(){o(new Error("load ".concat(e," error"))),n.onerror=null},n.src=e,document.getElementsByTagName("head")[0].appendChild(n)}))}function c(){return new Promise((function(t,o){setTimeout((function(){o(new Error("load ".concat(e," timeout")))}),n)}))}return Promise.race([i(),c()])}(i[c].url):Promise.reject(new Error("\u672a\u627e\u5230\u5bf9\u5e94\u7684sdk")):Promise.resolve(),v(),w},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).mpx=t(); \ No newline at end of file +var e,t;e=this,t=function(){"use strict";function e(e,t,o){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var o=e[Symbol.toPrimitive];if(void 0!==o){var n=o.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function t(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}var o,n,a,r,i=function(o){for(var n=1;n-1&&g.indexOf("MiniProgram")>-1?c="my":g.toLowerCase().indexOf("miniprogram")>-1?c=g.indexOf("QQ")>-1?"qq":"wx":g.indexOf("swan/")>-1?c="swan":g.indexOf("toutiao")>-1?c="tt":(c="web",window.addEventListener("message",(function(e){var t=e.data,o=t;try{"string"==typeof t&&(o=JSON.parse(t))}catch(e){}var n=o,a=n.callbackId,r=n.error,i=n.result;void 0!==a&&d[a]&&(r?d[a](r):d[a](null,i),delete d[a])}),!1));var u=!1;function w(e){u?e():o.then((function(){u=!0,e()}))}var l={config:function(e){"wx"===c?w((function(){window.wx&&window.wx.config(e)})):console.warn("\u975e\u5fae\u4fe1\u73af\u5883\u4e0d\u9700\u8981\u914d\u7f6econfig")}};function f(e){if("[object Object]"!==Object.prototype.toString.call(e))return e;var t={};for(var o in e)"function"!=typeof e[o]&&(t[o]=e[o]);return t}function m(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("getEnv"!==e){var o=++s;d[o]=function(e,n){e?(t.fail&&t.fail(e),t.complete&&t.complete(e)):(t.success&&t.success(n),t.complete&&t.complete(n)),delete d[o]};var n={type:e,callbackId:s,payload:f(t)};void 0!==p&&(n.clientUid=p),window.ReactNativeWebView?window.ReactNativeWebView.postMessage&&window.ReactNativeWebView.postMessage(JSON.stringify(n)):window.parent.postMessage&&window.parent.postMessage(n,"*")}else t({webapp:!0})}var v=function(){var e={wx:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","postMessage","getEnv"]},tt:{keyName:"miniProgram",api:["redirectTo","navigateTo","switchTab","reLaunch","navigateBack","setSwipeBackModeSync","postMessage","getEnv","checkJsApi","chooseImage","compressImage","previewImage","uploadFile","getNetworkType","openLocation","getLocation"]},swan:{keyName:"webView",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]},qq:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]}}[c]||{},t={wx:["checkJSApi","chooseImage","previewImage","uploadImage","downloadImage","getLocalImgData","startRecord","stopRecord","onVoiceRecordEnd","playVoice","pauseVoice","stopVoice","onVoicePlayEnd","uploadVoice","downloadVoice","translateVoice","getNetworkType","openLocation","getLocation","startSearchBeacons","stopSearchBeacons","onSearchBeacons","scanQRCode","chooseCard","addCard","openCard"],my:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","chooseImage","previewImage","getLocation","openLocation","alert","showLoading","hideLoading","getNetworkType","startShare","tradePay","postMessage","onMessage","getEnv"],swan:["makePhoneCall","setClipboardData","getNetworkType","openLocation","getLocation","chooseLocation","chooseImage","previewImage","openShare","navigateToSmartProgram"],web:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage","getLoadError","getLocation"],tt:[]}[c]||[];(e.api||[]).forEach((function(t){l[t]=function(){for(var o=arguments.length,n=new Array(o),a=0;a1&&void 0!==arguments[1]?arguments[1]:{},o=t.time,n=void 0===o?5e3:o,a=t.crossOrigin,r=void 0!==a&&a;function i(){return new Promise((function(t,o){var n=document.createElement("script");n.type="text/javascript",n.async="async",r&&(n.crossOrigin="anonymous"),n.onload=n.onreadystatechange=function(){this.readyState&&!/^(loaded|complete)$/.test(this.readyState)||(t(),n.onload=n.onreadystatechange=null)},n.onerror=function(){o(new Error("load ".concat(e," error"))),n.onerror=null},n.src=e,document.getElementsByTagName("head")[0].appendChild(n)}))}function c(){return new Promise((function(t,o){setTimeout((function(){o(new Error("load ".concat(e," timeout")))}),n)}))}return Promise.race([i(),c()])}(i[c].url):Promise.reject(new Error("\u672a\u627e\u5230\u5bf9\u5e94\u7684sdk")):Promise.resolve(),v(),l},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).mpx=t(); \ No newline at end of file diff --git a/lerna.json b/lerna.json index 706da83982..a007c6140a 100644 --- a/lerna.json +++ b/lerna.json @@ -1,3 +1,3 @@ { - "version": "2.9.55" + "version": "2.9.57" } \ No newline at end of file diff --git a/package.json b/package.json index f70dee24e6..44dd8243b7 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "test": "jest", "release": "npm run lint && npm run test && npx lerna version", "docs:dev": "vuepress dev docs-vuepress", - "docs:build": "vuepress build docs-vuepress" + "docs:build": "vuepress build docs-vuepress", + "tsc:build": "npm --workspace=./packages/webpack-plugin run build" }, "devDependencies": { "@babel/core": "^7.8.7", diff --git a/packages/api-proxy/@types/index.d.ts b/packages/api-proxy/@types/index.d.ts index 5b1aae93fc..cbfdb27fdd 100644 --- a/packages/api-proxy/@types/index.d.ts +++ b/packages/api-proxy/@types/index.d.ts @@ -2,16 +2,16 @@ type AddPromise = { [K in keyof W]: W[K] extends (...args: any) => any - ? Parameters extends [{ success?: (res: infer R) => any }?, ...any[]] - ? (...args: Parameters) => ReturnType & Promise + ? Parameters extends [{ success?: (res: infer R) => any }?, ...any[]] + ? (...args: Parameters) => ReturnType & Promise + : W[K] : W[K] - : W[K] } type AddParam any> = - Parameters extends [{ success?: (res: infer R) => any }, ...any[]] - ? (options: O) => ReturnType & Promise - : (options: O) => ReturnType + Parameters extends [{ success?: (res: infer R) => any }, ...any[]] + ? (options: O) => ReturnType & Promise + : (options: O) => ReturnType // @ts-ignore type PickApiValue = Pick[T] // @ts-ignore @@ -33,7 +33,7 @@ declare module '@mpxjs/core' { export const getProxy: (...args: any) => void -export const promisify: (listObj: object, whiteList: string[], customBlackList: string[]) => object +export const promisify: (listObj: object, whiteList?: string[], customBlackList?: string[]) => Record export const showActionSheet: WechatMiniprogram.Wx['showActionSheet'] export const addPhoneContact: WechatMiniprogram.Wx['addPhoneContact'] diff --git a/packages/api-proxy/package.json b/packages/api-proxy/package.json index af9fb84c65..95e55fa327 100644 --- a/packages/api-proxy/package.json +++ b/packages/api-proxy/package.json @@ -45,7 +45,11 @@ "@react-native-clipboard/clipboard": "^1.14.0", "@react-native-community/netinfo": "^11.2.1", "react-native-device-info": "^10.13.2", - "react-native-safe-area-context": "^4.10.1" + "react-native-safe-area-context": "^4.10.1", + "react-native-get-location": "^4.0.1", + "@ant-design/react-native": "^5.1.3", + "expo-brightness": "~11.8.0", + "react-native-webview": "^13.10.5" }, "peerDependenciesMeta": { "@react-native-async-storage/async-storage": { @@ -62,6 +66,18 @@ }, "react-native-safe-area-context": { "optional": true + }, + "react-native-get-location": { + "optional": true + }, + "@ant-design/react-native": { + "optional": true + }, + "expo-brightness": { + "optional": true + }, + "react-native-webview": { + "optional": true } } } diff --git a/packages/api-proxy/src/common/js/promisify.js b/packages/api-proxy/src/common/js/promisify.js index 76df420a27..3eb20590b4 100644 --- a/packages/api-proxy/src/common/js/promisify.js +++ b/packages/api-proxy/src/common/js/promisify.js @@ -29,7 +29,9 @@ const blackList = [ 'createOffscreenCanvas', 'reportEvent', 'connectSocket', - 'base64ToArrayBuffer' + 'base64ToArrayBuffer', + 'getDeviceInfo', + 'getWindowInfo' ] function getMapFromList (list) { diff --git a/packages/api-proxy/src/common/js/utils.js b/packages/api-proxy/src/common/js/utils.js index b358d2212d..6ea6baf195 100644 --- a/packages/api-proxy/src/common/js/utils.js +++ b/packages/api-proxy/src/common/js/utils.js @@ -77,6 +77,16 @@ function throwSSRWarning (info) { console.error(`[Mpx runtime error]: Dangerous API! ${info}, It may cause some problems, please use this method with caution`) } +function successHandle (result, success, complete) { + typeof success === 'function' && success(result) + typeof complete === 'function' && complete(result) +} + +function failHandle (result, fail, complete) { + typeof fail === 'function' && fail(result) + typeof complete === 'function' && complete(result) +} + const ENV_OBJ = getEnvObj() export { @@ -88,5 +98,7 @@ export { isBrowser, throwSSRWarning, ENV_OBJ, - defineUnsupportedProps + defineUnsupportedProps, + successHandle, + failHandle } diff --git a/packages/api-proxy/src/common/js/web.js b/packages/api-proxy/src/common/js/web.js index 6680b94346..b71bcd07c4 100644 --- a/packages/api-proxy/src/common/js/web.js +++ b/packages/api-proxy/src/common/js/web.js @@ -1,13 +1,3 @@ -function webHandleSuccess (result, success, complete) { - typeof success === 'function' && success(result) - typeof complete === 'function' && complete(result) -} - -function webHandleFail (result, fail, complete) { - typeof fail === 'function' && fail(result) - typeof complete === 'function' && complete(result) -} - function isTabBarPage (url, router) { const tabBarPagesMap = global.__tabBarPagesMap if (!tabBarPagesMap || !url) return false @@ -49,8 +39,6 @@ function getRootElement () { } export { - webHandleSuccess, - webHandleFail, createDom, bindTap, getRootElement, diff --git a/packages/api-proxy/src/platform/api/action-sheet/ActionSheet.js b/packages/api-proxy/src/platform/api/action-sheet/ActionSheet.js index a93618bb8f..8d4b9fc570 100644 --- a/packages/api-proxy/src/platform/api/action-sheet/ActionSheet.js +++ b/packages/api-proxy/src/platform/api/action-sheet/ActionSheet.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, webHandleFail, createDom, bindTap, getRootElement } from '../../../common/js' +import { successHandle, failHandle, createDom, bindTap, getRootElement } from '../../../common/js' import '../../../common/stylus/ActionSheet.styl' export default class ActionSheet { @@ -44,8 +44,7 @@ export default class ActionSheet { errMsg: 'showActionSheet:ok', tapIndex: index } - webHandleSuccess(res, opts.success, opts.complete) - // this.toPromiseResolve(res) + successHandle(res, opts.success, opts.complete) })) list.appendChild(sheet) }) @@ -57,8 +56,7 @@ export default class ActionSheet { this.tempListeners.push(bindTap(this.cancelBtn, () => { this.hide() const err = { errMsg: 'showActionSheet:fail cancel' } - webHandleFail(err, opts.fail, opts.complete) - // !opts.fail && this.toPromiseReject(err) + failHandle(err, opts.fail, opts.complete) })) // make transition next frame this.actionSheet.classList.add('show') @@ -66,8 +64,6 @@ export default class ActionSheet { setTimeout(() => { this.box.classList.add('show') }, 17) - - // return this.toPromiseInitPromise() } hide () { diff --git a/packages/api-proxy/src/platform/api/action-sheet/index.android.js b/packages/api-proxy/src/platform/api/action-sheet/index.android.js new file mode 100644 index 0000000000..b3e2901c06 --- /dev/null +++ b/packages/api-proxy/src/platform/api/action-sheet/index.android.js @@ -0,0 +1 @@ +export * from './rnActionSheet' diff --git a/packages/api-proxy/src/platform/api/action-sheet/index.ios.js b/packages/api-proxy/src/platform/api/action-sheet/index.ios.js new file mode 100644 index 0000000000..b3e2901c06 --- /dev/null +++ b/packages/api-proxy/src/platform/api/action-sheet/index.ios.js @@ -0,0 +1 @@ +export * from './rnActionSheet' diff --git a/packages/api-proxy/src/platform/api/action-sheet/rnActionSheet.jsx b/packages/api-proxy/src/platform/api/action-sheet/rnActionSheet.jsx new file mode 100644 index 0000000000..701cb92f93 --- /dev/null +++ b/packages/api-proxy/src/platform/api/action-sheet/rnActionSheet.jsx @@ -0,0 +1,127 @@ +import { View, TouchableHighlight, Text, StyleSheet, Button, Animated } from 'react-native' +import { successHandle, failHandle } from '../../../common/js' +import { Portal } from '@ant-design/react-native' +function showActionSheet (options) { + const { alertText, itemList = [], itemColor = '#000000', success, fail, complete } = options + let actionSheetKey + const slideAnim = new Animated.Value(500) + const slideIn = () => { + // Will change fadeAnim value to 1 in 5 seconds + Animated.timing(slideAnim, { + toValue: 0, + duration: 200, + useNativeDriver: true, + }).start() + } + const slideOut = () => { + // Will change fadeAnim value to 1 in 5 seconds + Animated.timing(slideAnim, { + toValue: 500, + duration: 200, + useNativeDriver: true, + }).start(() => { + }) + } + if (itemList.length === 0 || itemList.length > 6) { + const result = { + errMsg: 'showActionSheet:fail parameter error: itemList should not be large than 6' + } + if (itemList.length === 0) { + result.errno = 1001 + result.errMsg = 'showActionSheet:fail parameter error: parameter.itemList should have at least 1 item;' + } + failHandle(result, fail, complete) + return + } + const styles = StyleSheet.create({ + actionActionMask: { + left: 0, + top: 0, + bottom: 0, + right: 0, + backgroundColor: 'rgba(0,0,0,0.6)', + position: 'absolute', + zIndex: 1000 + }, + actionSheetContent: { + left: 0, + right: 0, + position: 'absolute', + bottom: 0, + backgroundColor: '#ffffff', + borderTopLeftRadius: 10, + borderTopRightRadius: 10, + transform: [{ + translateY: -500 + }] + }, + itemStyle: { + paddingTop: 15, + paddingBottom: 15, + justifyContent: 'center', + alignItems: 'center', + borderBottomWidth: 1, + borderBottomStyle: 'solid', + borderBottomColor: 'rgba(0,0,0,0.1)' + }, + itemTextStyle: { + fontSize: 18 + }, + buttonStyle: { + fontSize: 18, + paddingTop: 10, + paddingBottom: 10 + } + }) + const remove = function () { + if (actionSheetKey) { + slideOut() + setTimeout(() => { + Portal.remove(actionSheetKey) + actionSheetKey = null + }, 200) + } + } + const selectAction = function (index) { + const result = { + errMsg: 'showActionSheet:ok', + tapIndex: index + } + successHandle(result, success, complete) + remove() + } + const cancelAction = function () { + const result = { + errMsg: 'showActionSheet:fail cancel' + } + failHandle(result, fail, complete) + remove() + } + let alertTextList = [] + if (alertText) { + alertTextList = [alertText] + } + const ActionSheetView = + + { alertTextList.map((item, index) => {item}) } + { itemList.map((item, index) => selectAction(index)} style={ [styles.itemStyle, itemList.length -1 === index ? { + borderBottomWidth: 6, + borderBottomStyle: 'solid', + borderBottomColor: '#f7f7f7' + } : {}] }>{item}) } + + + + actionSheetKey = Portal.add(ActionSheetView) + slideIn() +} + +export { + showActionSheet +} diff --git a/packages/api-proxy/src/platform/api/clipboard-data/rnClipboard.js b/packages/api-proxy/src/platform/api/clipboard-data/rnClipboard.js index 99f97f6849..86bc77310f 100644 --- a/packages/api-proxy/src/platform/api/clipboard-data/rnClipboard.js +++ b/packages/api-proxy/src/platform/api/clipboard-data/rnClipboard.js @@ -1,5 +1,5 @@ import Clipboard from '@react-native-clipboard/clipboard' -import { webHandleSuccess, webHandleFail } from '../../../common/js/web' +import { successHandle, failHandle } from '../../../common/js' import { type } from '@mpxjs/utils' const setClipboardData = function (options) { const { data, success, fail, complete } = options @@ -9,14 +9,14 @@ const setClipboardData = function (options) { errno: 1001, errMsg: errStr } - webHandleFail(result, fail, complete) + failHandle(result, fail, complete) return } Clipboard.setString(data) const result = { errMsg: 'setClipboardData:ok' } - webHandleSuccess(result, success, complete) + successHandle(result, success, complete) } const getClipboardData = function (options) { @@ -26,12 +26,12 @@ const getClipboardData = function (options) { data, errMsg: 'getClipboardData:ok' } - webHandleSuccess(result, success, complete) + successHandle(result, success, complete) }).catch(() => { const result = { errMsg: 'setClipboardData:fail' } - webHandleFail(result, fail, complete) + failHandle(result, fail, complete) }) } diff --git a/packages/api-proxy/src/platform/api/device/network/getNetworkType.js b/packages/api-proxy/src/platform/api/device/network/getNetworkType.js index 81a8651ef5..0c212560b1 100644 --- a/packages/api-proxy/src/platform/api/device/network/getNetworkType.js +++ b/packages/api-proxy/src/platform/api/device/network/getNetworkType.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, webHandleFail, isBrowser, throwSSRWarning } from '../../../../common/js' +import { successHandle, failHandle, isBrowser, throwSSRWarning } from '../../../../common/js' export function getNetworkType ({ success, fail = () => {}, complete = () => {} } = {}) { if (!isBrowser) { @@ -7,11 +7,11 @@ export function getNetworkType ({ success, fail = () => {}, complete = () => {} } try { if (navigator.connection) { - webHandleSuccess({ networkType: navigator.connection.effectiveType }, success, complete) + successHandle({ networkType: navigator.connection.effectiveType }, success, complete) } else { - webHandleSuccess({ networkType: 'unknown' }, success, complete) + successHandle({ networkType: 'unknown' }, success, complete) } } catch (err) { - webHandleFail(err, fail, complete) + failHandle(err, fail, complete) } } diff --git a/packages/api-proxy/src/platform/api/device/network/rnNetwork.js b/packages/api-proxy/src/platform/api/device/network/rnNetwork.js index bf976cce3f..bacffc593f 100644 --- a/packages/api-proxy/src/platform/api/device/network/rnNetwork.js +++ b/packages/api-proxy/src/platform/api/device/network/rnNetwork.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, webHandleFail, defineUnsupportedProps } from '../../../../common/js' +import { successHandle, failHandle, defineUnsupportedProps } from '../../../../common/js' import NetInfo, { NetInfoStateType } from '@react-native-community/netinfo' let _unsubscribe = null @@ -21,12 +21,12 @@ const getNetworkType = function (options) { errMsg: 'getNetworkType:ok' } defineUnsupportedProps(result, ['signalStrength', 'hasSystemProxy']) - webHandleSuccess(result, success, complete) + successHandle(result, success, complete) }).catch((err) => { const result = { errMsg: err.message } - webHandleFail(result, fail, complete) + failHandle(result, fail, complete) }) } diff --git a/packages/api-proxy/src/platform/api/image/Preview.js b/packages/api-proxy/src/platform/api/image/Preview.js index 5ac00d83bd..f42f3d0c42 100644 --- a/packages/api-proxy/src/platform/api/image/Preview.js +++ b/packages/api-proxy/src/platform/api/image/Preview.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, webHandleFail, createDom, warn, bindTap, getRootElement } from '../../../common/js' +import { successHandle, failHandle, createDom, warn, bindTap, getRootElement } from '../../../common/js' import '../../../common/stylus/Preview.styl' /** * Preview class for displaying images in a slideshow format. @@ -67,9 +67,9 @@ export default class Preview { })))) this.maxIndex = urls.length this.updateTextTip() - webHandleSuccess({ errMsg: 'previewImage:ok' }, success, complete) + successHandle({ errMsg: 'previewImage:ok' }, success, complete) } catch (e) { - webHandleFail({ errMsg: 'previewImage:fail', err: e }, fail, complete) + failHandle({ errMsg: 'previewImage:fail', err: e }, fail, complete) } } diff --git a/packages/api-proxy/src/platform/api/location/index.ali.js b/packages/api-proxy/src/platform/api/location/index.ali.js new file mode 100644 index 0000000000..12dee79583 --- /dev/null +++ b/packages/api-proxy/src/platform/api/location/index.ali.js @@ -0,0 +1,31 @@ +import { ENV_OBJ, changeOpts, handleSuccess, defineUnsupportedProps } from '../../../common/js' + +function getLocation (options = {}) { + const opts = Object.assign(options, { + type: 0 // 只获取经纬与微信拉齐 + }) + handleSuccess(opts, res => { + const result = changeOpts( + res, + { errMsg: 'getLocation:ok' } + ) + defineUnsupportedProps(result, ['speed']) + return result + }) + return ENV_OBJ.getLocation(opts) +} + +function openLocation (options = {}) { + const opts = Object.assign({ + scale: 15 // 地图缩放比例兜底值 + }, options) + return ENV_OBJ.openLocation(opts) +} + +const chooseLocation = ENV_OBJ.chooseLocation + +export { + getLocation, + openLocation, + chooseLocation +} diff --git a/packages/api-proxy/src/platform/api/location/index.android.js b/packages/api-proxy/src/platform/api/location/index.android.js new file mode 100644 index 0000000000..25aabdbcf9 --- /dev/null +++ b/packages/api-proxy/src/platform/api/location/index.android.js @@ -0,0 +1 @@ +export * from './index.ios' diff --git a/packages/api-proxy/src/platform/api/location/index.ios.js b/packages/api-proxy/src/platform/api/location/index.ios.js new file mode 100644 index 0000000000..78e0703e37 --- /dev/null +++ b/packages/api-proxy/src/platform/api/location/index.ios.js @@ -0,0 +1,31 @@ +import GetLocation from 'react-native-get-location' +import { envError, successHandle, failHandle, defineUnsupportedProps } from '../../../common/js' + +const getLocation = function (options) { + const { isHighAccuracy = false, success, fail, complete } = options + GetLocation.getCurrentPosition({ + enableHighAccuracy: isHighAccuracy + }).then(location => { + Object.assign(location, { + errMsg: 'getLocation:ok' + }) + defineUnsupportedProps(location, ['horizontalAccuracy']) + successHandle(location, success, complete) + }) + .catch(error => { + const result = { + errMsg: `getLocation:fail ${error}` + } + failHandle(result, fail, complete) + }) +} + +const openLocation = envError('openLocation') + +const chooseLocation = envError('chooseLocation') + +export { + getLocation, + openLocation, + chooseLocation +} diff --git a/packages/api-proxy/src/platform/api/location/index.js b/packages/api-proxy/src/platform/api/location/index.js new file mode 100644 index 0000000000..4eca32aedd --- /dev/null +++ b/packages/api-proxy/src/platform/api/location/index.js @@ -0,0 +1,13 @@ +import { ENV_OBJ, envError } from '../../../common/js' + +const getLocation = ENV_OBJ.getLocation || envError('getLocation') + +const openLocation = ENV_OBJ.openLocation || envError('openLocation') + +const chooseLocation = ENV_OBJ.chooseLocation || envError('chooseLocation') + +export { + getLocation, + openLocation, + chooseLocation +} diff --git a/packages/api-proxy/src/platform/api/location/index.web.js b/packages/api-proxy/src/platform/api/location/index.web.js new file mode 100644 index 0000000000..c9208e5e4c --- /dev/null +++ b/packages/api-proxy/src/platform/api/location/index.web.js @@ -0,0 +1,36 @@ +import { envError, successHandle, failHandle, defineUnsupportedProps } from '../../../common/js' + +const getLocation = function (options) { + const { isHighAccuracy = false, success, fail, complete } = options + if (navigator.geolocation.getCurrentPosition) { + navigator.geolocation.getCurrentPosition((res = {}) => { + const coords = res.coords || {} + const result = { + accuracy: coords.accuracy, + errMsg: 'getLocation:ok', + latitude: coords.latitude, + longitude: coords.longitude, + speed: coords.accuracy + } + defineUnsupportedProps(result, ['horizontalAccuracy', 'verticalAccuracy']) + successHandle(result, success, complete) + }, (err) => { + const result = { + errMsg: `getLocation:fail ${err}` + } + failHandle(result, fail, complete) + }, { + enableHighAccuracy: isHighAccuracy + }) + } +} + +const openLocation = envError('openLocation') + +const chooseLocation = envError('chooseLocation') + +export { + getLocation, + openLocation, + chooseLocation +} diff --git a/packages/api-proxy/src/platform/api/make-phone-call/rnMakePhone.js b/packages/api-proxy/src/platform/api/make-phone-call/rnMakePhone.js index a3b3ecc394..2a3a8b5fd1 100644 --- a/packages/api-proxy/src/platform/api/make-phone-call/rnMakePhone.js +++ b/packages/api-proxy/src/platform/api/make-phone-call/rnMakePhone.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, webHandleFail } from '../../../common/js' +import { successHandle, failHandle } from '../../../common/js' import { Linking } from 'react-native' const makePhoneCall = function (options) { @@ -13,12 +13,12 @@ const makePhoneCall = function (options) { const result = { errMsg: 'makePhoneCall:ok' } - webHandleSuccess(result, success, complete) + successHandle(result, success, complete) }).catch(() => { const result = { errMsg: 'makePhoneCall:fail cancel' } - webHandleFail(result, fail, complete) + failHandle(result, fail, complete) }) } diff --git a/packages/api-proxy/src/platform/api/modal/Modal.js b/packages/api-proxy/src/platform/api/modal/Modal.js index 2086dde5cd..352f9ba9de 100644 --- a/packages/api-proxy/src/platform/api/modal/Modal.js +++ b/packages/api-proxy/src/platform/api/modal/Modal.js @@ -1,4 +1,4 @@ -import { createDom, getRootElement, webHandleSuccess } from '../../../common/js' +import { createDom, getRootElement, successHandle, failHandle } from '../../../common/js' import '../../../common/stylus/Modal.styl' // import { forEach } from '@didi/mpx-fetch/src/util' // 汉字为两个字符,字母/数字为一个字符 @@ -23,9 +23,9 @@ export default class Modal { cancelColor: '#000000', confirmText: '确定', confirmColor: '#576B95', - success: (...args) => {}, - fail: (...args) => {}, - complete: (...args) => {} + success: (...args) => { }, + fail: (...args) => { }, + complete: (...args) => { } } this.hideTimer = null @@ -44,21 +44,18 @@ export default class Modal { } show (options = {}) { - getRootElement().appendChild(this.modal) - if (options.confirmText && _getLength(options.confirmText) > 8) { - // eslint-disable-next-line - return Promise.reject({errMsg: 'showModal:fail confirmText length should not larger than 4 Chinese characters'}) + const opts = Object.assign({}, this.defaultOpts, options) + if (opts.confirmText && _getLength(opts.confirmText) > 8) { + return failHandle({ errMsg: 'showModal:fail confirmText length should not larger than 4 Chinese characters' }, opts.fail, opts.complete) } - if (options.cancelText && _getLength(options.cancelText) > 8) { - // eslint-disable-next-line - return Promise.reject({errMsg: 'showModal:fail cancelText length should not larger than 4 Chinese characters'}) + if (opts.cancelText && _getLength(opts.cancelText) > 8) { + return failHandle({ errMsg: 'showModal:fail cancelText length should not larger than 4 Chinese characters' }, opts.fail, opts.complete) } + getRootElement().appendChild(this.modal) if (this.hideTimer) { clearTimeout(this.hideTimer) this.hideTimer = null } - const opts = Object.assign({}, this.defaultOpts, options) - this.title.textContent = opts.title this.content.textContent = opts.content @@ -80,7 +77,7 @@ export default class Modal { cancel: true, confirm: false } - webHandleSuccess(result, opts.success, opts.complete) + successHandle(result, opts.success, opts.complete) } this.confirmBtn.onclick = () => { this.hide() @@ -89,7 +86,7 @@ export default class Modal { cancel: false, confirm: true } - webHandleSuccess(result, opts.success, opts.complete) + successHandle(result, opts.success, opts.complete) } this.modal.classList.add('show') diff --git a/packages/api-proxy/src/platform/api/modal/index.android.js b/packages/api-proxy/src/platform/api/modal/index.android.js new file mode 100644 index 0000000000..42f1744c80 --- /dev/null +++ b/packages/api-proxy/src/platform/api/modal/index.android.js @@ -0,0 +1 @@ +export * from './rnModal' diff --git a/packages/api-proxy/src/platform/api/modal/index.ios.js b/packages/api-proxy/src/platform/api/modal/index.ios.js new file mode 100644 index 0000000000..42f1744c80 --- /dev/null +++ b/packages/api-proxy/src/platform/api/modal/index.ios.js @@ -0,0 +1 @@ +export * from './rnModal' diff --git a/packages/api-proxy/src/platform/api/modal/rnModal.jsx b/packages/api-proxy/src/platform/api/modal/rnModal.jsx new file mode 100644 index 0000000000..efe8120a7b --- /dev/null +++ b/packages/api-proxy/src/platform/api/modal/rnModal.jsx @@ -0,0 +1,149 @@ +import { View, Dimensions, Text, StyleSheet, TouchableOpacity, ScrollView } from 'react-native' +import { successHandle, failHandle } from '../../../common/js' +import { Portal } from '@ant-design/react-native' +const { width, height } = Dimensions.get('window') +const showModal = function (options) { + const { + title, + content, + showCancel = true, + cancelText = '取消', + cancelColor = '#000000', + confirmText = '确定', + confirmColor = '#576B95', + editable = false, + placeholderText, + success, + fail, + complete + } = options + const modalWidth = width - 60 + const styles = StyleSheet.create({ + modalTask: { + width, + height, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: 'rgba(0,0,0,0.6)', + position: 'absolute' + }, + modalContent: { + paddingTop: 20, + width: modalWidth, + backgroundColor: '#ffffff', + borderRadius: 15, + justifyContent: 'center', + alignItems: 'center' + }, + modalTitleText: { + fontSize: 18, + fontWeight: 'bold', + paddingLeft: 20, + paddingRight: 20 + }, + contentBox: { + maxHeight: height * 0.45, + marginTop: 10 + }, + modalContentText: { + fontSize: 16, + lineHeight: 26, + color: '#808080', + paddingLeft: 20, + paddingRight: 20 + }, + modalBtnBox: { + borderTopWidth: StyleSheet.hairlineWidth, + borderTopColor: 'rgba(0,0,0,0.2)', + borderStyle: 'solid', + marginTop: 25, + width: '100%', + display: 'flex', + flexDirection: 'row' + }, + modalBtn: { + flex: 1, + textAlign: 'center', + paddingTop: 10, + paddingBottom: 10, + }, + modalButton: { + width: '100%', + fontWeight: 'bold', + textAlign: 'center' + }, + cancelStyle: { + borderRightWidth: StyleSheet.hairlineWidth, + borderRightColor: 'rgba(0,0,0,0.2)', + borderStyle: 'solid', + } + }) + let modalKey + let ModalView + let modalTitle = [] + let modalContent = [] + let modalButton = [{ + text: confirmText, + confirmColor, + type: 'confirm', + color: 'rgb(87, 107, 149)' + }] + const closeModal = function (buttonInfo) { + Portal.remove(modalKey) + modalKey = null + const result = { + errMsg: 'showModal:ok' + } + if (buttonInfo.type === 'confirm') { + Object.assign(result, { + confirm: true, + cancel: false, + content: null + }) + } else { + Object.assign(result, { + confirm: false, + cancel: true + }) + } + successHandle(result, success, complete) + } + if (title) { + modalTitle.push(title) + } + if (!editable && content) { + modalContent.push(content) + } + if (showCancel) { + modalButton.unshift({ + text: cancelText, + cancelColor, + type: 'cancel', + style: styles.cancelStyle, + color: '#000000' + }) + } + if (!editable) { + ModalView = + + {modalTitle.map((item, index) => {item})} + {modalContent.map((item, index) => {item})} + + {modalButton.map((item, index) => closeModal(item)}>{item.text})} + + + + } + try { + modalKey = Portal.add(ModalView) + } catch (e) { + const result = { + errMsg: `showModal:fail invalid ${e}` + } + failHandle(result, fail, complete) + } +} + +export { + showModal +} diff --git a/packages/api-proxy/src/platform/api/next-tick/index.android.js b/packages/api-proxy/src/platform/api/next-tick/index.android.js new file mode 100644 index 0000000000..e482a0cd5e --- /dev/null +++ b/packages/api-proxy/src/platform/api/next-tick/index.android.js @@ -0,0 +1 @@ +export * from './index.ali' diff --git a/packages/api-proxy/src/platform/api/next-tick/index.ios.js b/packages/api-proxy/src/platform/api/next-tick/index.ios.js new file mode 100644 index 0000000000..e482a0cd5e --- /dev/null +++ b/packages/api-proxy/src/platform/api/next-tick/index.ios.js @@ -0,0 +1 @@ +export * from './index.ali' diff --git a/packages/api-proxy/src/platform/api/page-scroll-to/index.web.js b/packages/api-proxy/src/platform/api/page-scroll-to/index.web.js index 73477c8795..aed1d664ba 100644 --- a/packages/api-proxy/src/platform/api/page-scroll-to/index.web.js +++ b/packages/api-proxy/src/platform/api/page-scroll-to/index.web.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, webHandleFail, isBrowser, throwSSRWarning } from '../../../common/js' +import { successHandle, failHandle, isBrowser, throwSSRWarning } from '../../../common/js' import { nextTick } from '../next-tick' export function pageScrollTo (options) { @@ -11,13 +11,13 @@ export function pageScrollTo (options) { const { success, fail, complete } = options if (!ms) { - return webHandleFail({ + return failHandle({ errMsg: 'pageScrollTo:fail' }, fail, complete) } ms.pageScrollTo(options) - webHandleSuccess({ + successHandle({ errMsg: 'pageScrollTo:ok' }, success, complete) }) diff --git a/packages/api-proxy/src/platform/api/pull-down/index.web.js b/packages/api-proxy/src/platform/api/pull-down/index.web.js index 98f7a79cd2..d9bbab1bbb 100644 --- a/packages/api-proxy/src/platform/api/pull-down/index.web.js +++ b/packages/api-proxy/src/platform/api/pull-down/index.web.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, webHandleFail, throwSSRWarning, isBrowser } from '../../../common/js' +import { successHandle, failHandle, throwSSRWarning, isBrowser } from '../../../common/js' function stopPullDownRefresh (options = {}) { if (!isBrowser) { @@ -22,10 +22,10 @@ function stopPullDownRefresh (options = {}) { } if (err) { const res = { errMsg: `stopPullDownRefresh:fail ${err}` } - webHandleFail(res, options.fail, options.complete) + failHandle(res, options.fail, options.complete) } else { const res = { errMsg: 'stopPullDownRefresh:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) } } } @@ -52,10 +52,10 @@ function startPullDownRefresh (options = {}) { } if (err) { const res = { errMsg: `startPullDownRefresh:fail ${err}` } - webHandleFail(res, options.fail, options.complete) + failHandle(res, options.fail, options.complete) } else { const res = { errMsg: 'startPullDownRefresh:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) } } } diff --git a/packages/api-proxy/src/platform/api/request/index.web.js b/packages/api-proxy/src/platform/api/request/index.web.js index 783c99e23c..9930d9b9ea 100644 --- a/packages/api-proxy/src/platform/api/request/index.web.js +++ b/packages/api-proxy/src/platform/api/request/index.web.js @@ -1,5 +1,5 @@ import axios from 'axios' -import { webHandleSuccess, webHandleFail, defineUnsupportedProps } from '../../../common/js' +import { successHandle, failHandle, defineUnsupportedProps } from '../../../common/js' import RequestTask from './RequestTask' function request (options = { url: '' }) { @@ -70,7 +70,7 @@ function request (options = { url: '' }) { header: res.headers } defineUnsupportedProps(result, ['cookies', 'profile', 'exception']) - webHandleSuccess(result, success, complete) + successHandle(result, success, complete) return result }).catch(err => { const response = err?.response || {} @@ -80,10 +80,7 @@ function request (options = { url: '' }) { header: response.headers, data: response.data } - webHandleFail(res, fail, complete) - if (!fail) { - return Promise.reject(res) - } + failHandle(res, fail, complete) }) return requestTask diff --git a/packages/api-proxy/src/platform/api/route/index.ios.js b/packages/api-proxy/src/platform/api/route/index.ios.js index 6c167e95db..ba46e396b7 100644 --- a/packages/api-proxy/src/platform/api/route/index.ios.js +++ b/packages/api-proxy/src/platform/api/route/index.ios.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, webHandleFail } from '../../../common/js' +import { successHandle, failHandle } from '../../../common/js' import { parseQuery } from '@mpxjs/utils' function parseUrl (url) { @@ -58,11 +58,11 @@ function navigateTo (options = {}) { navigation.push(finalPath, queryObj) navigationHelper.lastSuccessCallback = () => { const res = { errMsg: 'navigateTo:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) } navigationHelper.lastFailCallback = (msg) => { const res = { errMsg: `navigateTo:fail ${msg}` } - webHandleFail(res, options.fail, options.complete) + failHandle(res, options.fail, options.complete) } } } @@ -77,11 +77,11 @@ function redirectTo (options = {}) { navigation.replace(finalPath, queryObj) navigationHelper.lastSuccessCallback = () => { const res = { errMsg: 'redirectTo:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) } navigationHelper.lastFailCallback = (msg) => { const res = { errMsg: `redirectTo:fail ${msg}` } - webHandleFail(res, options.fail, options.complete) + failHandle(res, options.fail, options.complete) } } } @@ -93,11 +93,11 @@ function navigateBack (options = {}) { navigation.pop(options.delta || 1) navigationHelper.lastSuccessCallback = () => { const res = { errMsg: 'navigateBack:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) } navigationHelper.lastFailCallback = (msg) => { const res = { errMsg: `navigateBack:fail ${msg}` } - webHandleFail(res, options.fail, options.complete) + failHandle(res, options.fail, options.complete) } } } @@ -120,11 +120,11 @@ function reLaunch (options = {}) { }) navigationHelper.lastSuccessCallback = () => { const res = { errMsg: 'redirectTo:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) } navigationHelper.lastFailCallback = (msg) => { const res = { errMsg: `redirectTo:fail ${msg}` } - webHandleFail(res, options.fail, options.complete) + failHandle(res, options.fail, options.complete) } } } diff --git a/packages/api-proxy/src/platform/api/route/index.web.js b/packages/api-proxy/src/platform/api/route/index.web.js index 89140ea255..1d6f0153e4 100644 --- a/packages/api-proxy/src/platform/api/route/index.web.js +++ b/packages/api-proxy/src/platform/api/route/index.web.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, webHandleFail, isTabBarPage, throwSSRWarning, isBrowser } from '../../../common/js' +import { successHandle, failHandle, isTabBarPage, throwSSRWarning, isBrowser } from '../../../common/js' import { EventChannel } from '../event-channel' let routeCount = 0 @@ -12,8 +12,7 @@ function redirectTo (options = {}) { if (router) { if (isTabBarPage(options.url, router)) { const res = { errMsg: 'redirectTo:fail can not redirectTo a tabBar page' } - webHandleFail(res, options.fail, options.complete) - return Promise.reject(res) + failHandle(res, options.fail, options.complete) } router.__mpxAction = { type: 'redirect' } if (routeCount === 0 && router.currentRoute.query.routeCount) routeCount = router.currentRoute.query.routeCount @@ -26,11 +25,11 @@ function redirectTo (options = {}) { }, () => { const res = { errMsg: 'redirectTo:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) }, err => { const res = { errMsg: `redirectTo:fail ${err}` } - webHandleFail(res, options.fail, options.complete) + failHandle(res, options.fail, options.complete) } ) } @@ -45,8 +44,7 @@ function navigateTo (options = {}) { if (router) { if (isTabBarPage(options.url, router)) { const res = { errMsg: 'navigateTo:fail can not navigateTo a tabBar page' } - webHandleFail(res, options.fail, options.complete) - return Promise.reject(res) + failHandle(res, options.fail, options.complete) } const eventChannel = new EventChannel() router.__mpxAction = { @@ -66,11 +64,11 @@ function navigateTo (options = {}) { }, () => { const res = { errMsg: 'navigateTo:ok', eventChannel } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) }, err => { const res = { errMsg: `navigateTo:fail ${err}` } - webHandleFail(res, options.fail, options.complete) + failHandle(res, options.fail, options.complete) } ) } @@ -94,7 +92,7 @@ function navigateBack (options = {}) { } router.go(-delta) const res = { errMsg: 'navigateBack:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) } } @@ -127,16 +125,16 @@ function reLaunch (options = {}) { }, () => { const res = { errMsg: 'reLaunch:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) }, err => { const res = { errMsg: `reLaunch:fail ${err}` } - webHandleFail(res, options.fail, options.complete) + failHandle(res, options.fail, options.complete) } ) } const res = { errMsg: 'reLaunch:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) } } @@ -152,8 +150,7 @@ function switchTab (options = {}) { if (toRoute.path !== currentRoute.path) { if (!isTabBarPage(options.url, router)) { const res = { errMsg: 'switchTab:fail can not switch to no-tabBar page!' } - webHandleFail(res, options.fail, options.complete) - return Promise.reject(res) + failHandle(res, options.fail, options.complete) } router.__mpxAction = { type: 'switch', @@ -171,17 +168,17 @@ function switchTab (options = {}) { }, () => { const res = { errMsg: 'switchTab:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) }, err => { const res = { errMsg: `switchTab:fail ${err}` } - webHandleFail(res, options.fail, options.complete) + failHandle(res, options.fail, options.complete) } ) } } const res = { errMsg: 'switchTab:ok' } - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) } } diff --git a/packages/api-proxy/src/platform/api/screen-brightness/index.android.js b/packages/api-proxy/src/platform/api/screen-brightness/index.android.js new file mode 100644 index 0000000000..3d7b0c536a --- /dev/null +++ b/packages/api-proxy/src/platform/api/screen-brightness/index.android.js @@ -0,0 +1 @@ +export * from './rnScreenBrightness' diff --git a/packages/api-proxy/src/platform/api/screen-brightness/index.ios.js b/packages/api-proxy/src/platform/api/screen-brightness/index.ios.js new file mode 100644 index 0000000000..3d7b0c536a --- /dev/null +++ b/packages/api-proxy/src/platform/api/screen-brightness/index.ios.js @@ -0,0 +1 @@ +export * from './rnScreenBrightness' diff --git a/packages/api-proxy/src/platform/api/screen-brightness/rnScreenBrightness.js b/packages/api-proxy/src/platform/api/screen-brightness/rnScreenBrightness.js new file mode 100644 index 0000000000..907245018a --- /dev/null +++ b/packages/api-proxy/src/platform/api/screen-brightness/rnScreenBrightness.js @@ -0,0 +1,38 @@ +import * as Brightness from 'expo-brightness' +import { successHandle, failHandle } from '../../../common/js' + +function getScreenBrightness (options) { + const { success, fail, complete } = options + Brightness.getBrightnessAsync().then(value => { + const result = { + errMsg: 'getScreenBrightness:ok', + value + } + successHandle(result, success, complete) + }).catch(() => { + const result = { + errMsg: 'getScreenBrightness:fail' + } + failHandle(result, fail, complete) + }) +} + +function setScreenBrightness (options) { + const { value, success, fail, complete } = options + Brightness.setBrightnessAsync(value).then(() => { + const result = { + errMsg: 'setScreenBrightness:ok' + } + successHandle(result, success, complete) + }).catch(() => { + const result = { + errMsg: 'setScreenBrightness:fail' + } + failHandle(result, fail, complete) + }) +} + +export { + getScreenBrightness, + setScreenBrightness +} diff --git a/packages/api-proxy/src/platform/api/set-navigation-bar/index.android.js b/packages/api-proxy/src/platform/api/set-navigation-bar/index.android.js new file mode 100644 index 0000000000..25aabdbcf9 --- /dev/null +++ b/packages/api-proxy/src/platform/api/set-navigation-bar/index.android.js @@ -0,0 +1 @@ +export * from './index.ios' diff --git a/packages/api-proxy/src/platform/api/set-navigation-bar/index.ios.js b/packages/api-proxy/src/platform/api/set-navigation-bar/index.ios.js new file mode 100644 index 0000000000..8e8cc61e87 --- /dev/null +++ b/packages/api-proxy/src/platform/api/set-navigation-bar/index.ios.js @@ -0,0 +1,41 @@ +import { successHandle, failHandle } from '../../../common/js' + +function getFocusedNavigation () { + for (const key in global.__mpxPagesMap) { + const navigation = global.__mpxPagesMap[key]?.[1] + if (navigation && navigation.isFocused()) { + return navigation + } + } +} +function setNavigationBarTitle (options = {}) { + const { title = '', success, fail, complete } = options + const navigation = getFocusedNavigation() + if (!(navigation && navigation.setOptions)) { + failHandle({ errMsg: 'setNavigationBarTitle:fail' }, fail, complete) + } else { + navigation.setOptions({ headerTitle: title }) + successHandle({ errMsg: 'setNavigationBarTitle:ok' }, success, complete) + } +} + +function setNavigationBarColor (options = {}) { + const { frontColor = '', backgroundColor = '', success, fail, complete } = options + const navigation = getFocusedNavigation() + if (!(navigation && navigation.setOptions)) { + failHandle({ errMsg: 'setNavigationBarColor:fail' }, fail, complete) + } else { + navigation.setOptions({ + headerStyle: { + backgroundColor: backgroundColor + }, + headerTintColor: frontColor + }) + successHandle({ errMsg: 'setNavigationBarColor:ok' }, success, complete) + } +} + +export { + setNavigationBarTitle, + setNavigationBarColor +} diff --git a/packages/api-proxy/src/platform/api/set-navigation-bar/index.web.js b/packages/api-proxy/src/platform/api/set-navigation-bar/index.web.js index d0c258a058..487912e1d4 100644 --- a/packages/api-proxy/src/platform/api/set-navigation-bar/index.web.js +++ b/packages/api-proxy/src/platform/api/set-navigation-bar/index.web.js @@ -1,4 +1,4 @@ -import { isBrowser, throwSSRWarning, webHandleSuccess } from '../../../common/js' +import { isBrowser, throwSSRWarning, successHandle } from '../../../common/js' function setNavigationBarTitle (options = {}) { if (!isBrowser) { @@ -10,7 +10,7 @@ function setNavigationBarTitle (options = {}) { document.title = title } - webHandleSuccess({ errMsg: 'setNavigationBarTitle:ok' }, success, complete) + successHandle({ errMsg: 'setNavigationBarTitle:ok' }, success, complete) } function setNavigationBarColor (options = {}) { @@ -23,7 +23,7 @@ function setNavigationBarColor (options = {}) { meta.setAttribute('name', 'theme-color') meta.setAttribute('content', backgroundColor) document.head.appendChild(meta) - webHandleSuccess({ errMsg: 'setNavigationBarColor:ok' }, success, complete) + successHandle({ errMsg: 'setNavigationBarColor:ok' }, success, complete) } export { diff --git a/packages/api-proxy/src/platform/api/socket/SocketTask.js b/packages/api-proxy/src/platform/api/socket/SocketTask.js index d08496f978..0ae41ae7e9 100644 --- a/packages/api-proxy/src/platform/api/socket/SocketTask.js +++ b/packages/api-proxy/src/platform/api/socket/SocketTask.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, webHandleFail } from '../../../common/js' +import { successHandle, failHandle } from '../../../common/js' import { type } from '@mpxjs/utils' const socketTasks = new Set() @@ -44,20 +44,14 @@ class SocketTask { const { data = '', success, fail, complete } = options if (typeof data !== 'string' || type(data) !== 'ArrayBuffer') { const res = { errMsg: 'sendSocketMessage:fail Unsupported data type' } - webHandleFail(res, fail, complete) - return - } - if (this._socket.readyState === 1) { + failHandle(res, fail, complete) + } else if (this._socket.readyState === 1) { this._socket.send(data) const res = { errMsg: 'sendSocketMessage:ok' } - webHandleSuccess(res, success, complete) - return Promise.resolve(res) + successHandle(res, success, complete) } else { const res = { errMsg: 'sendSocketMessage:fail' } - webHandleFail(res, fail, complete) - if (!fail) { - return Promise.reject(res) - } + failHandle(res, fail, complete) } } @@ -70,14 +64,10 @@ class SocketTask { try { this._socket.close() const res = { errMsg: 'closeSocket:ok' } - webHandleSuccess(res, success, complete) - return Promise.resolve(res) + successHandle(res, success, complete) } catch (err) { const res = { errMsg: `closeSocket:fail ${err}` } - webHandleFail(res, fail, complete) - if (!fail) { - return Promise.reject(res) - } + failHandle(res, fail, complete) } } diff --git a/packages/api-proxy/src/platform/api/socket/index.web.js b/packages/api-proxy/src/platform/api/socket/index.web.js index d8aadb5eef..3b5137affe 100644 --- a/packages/api-proxy/src/platform/api/socket/index.web.js +++ b/packages/api-proxy/src/platform/api/socket/index.web.js @@ -1,4 +1,4 @@ -import { warn, webHandleSuccess, webHandleFail, isBrowser, throwSSRWarning } from '../../../common/js' +import { warn, successHandle, failHandle, isBrowser, throwSSRWarning } from '../../../common/js' import SocketTask from './SocketTask' function connectSocket (options = { url: '' }) { @@ -10,10 +10,10 @@ function connectSocket (options = { url: '' }) { try { const socketTask = new SocketTask(url, protocols) - webHandleSuccess({ errMsg: 'connectSocket:ok' }, success, complete) + successHandle({ errMsg: 'connectSocket:ok' }, success, complete) return socketTask } catch (e) { - webHandleFail({ errMsg: `connectSocket:fail ${e}` }, fail, complete) + failHandle({ errMsg: `connectSocket:fail ${e}` }, fail, complete) } } diff --git a/packages/api-proxy/src/platform/api/storage/index.web.js b/packages/api-proxy/src/platform/api/storage/index.web.js index c8e3cb4f22..6def4c90ba 100644 --- a/packages/api-proxy/src/platform/api/storage/index.web.js +++ b/packages/api-proxy/src/platform/api/storage/index.web.js @@ -1,5 +1,4 @@ - -import { webHandleSuccess, webHandleFail, isBrowser, throwSSRWarning } from '../../../common/js' +import { successHandle, failHandle, isBrowser, throwSSRWarning } from '../../../common/js' import { hasOwn } from '@mpxjs/utils' function setStorage (options = {}) { @@ -13,10 +12,10 @@ function setStorage (options = {}) { setStorageSync(key, data) const res = { errMsg: 'setStorage:ok' } - webHandleSuccess(res, success, complete) + successHandle(res, success, complete) } catch (err) { const res = { errMsg: `setStorage:fail ${err}` } - webHandleFail(res, fail, complete) + failHandle(res, fail, complete) } } @@ -45,10 +44,10 @@ function getStorage (options = {}) { if (result) { const res = { errMsg: 'getStorage:ok', data: data } - webHandleSuccess(res, success, complete) + successHandle(res, success, complete) } else { const res = { errMsg: 'getStorage:fail', data: null } - webHandleFail(res, fail, complete) + failHandle(res, fail, complete) } } @@ -88,10 +87,10 @@ function getStorageInfo (options = {}) { const info = getStorageInfoSync() const res = Object.assign({}, { errMsg: 'getStorageInfo:ok' }, info) - webHandleSuccess(res, success, complete) + successHandle(res, success, complete) } catch (err) { const res = { errMsg: `getStorageInfo:fail ${err}` } - webHandleFail(res, fail, complete) + failHandle(res, fail, complete) } } @@ -118,10 +117,10 @@ function removeStorage (options = { key: '' }) { removeStorageSync(key) const res = { errMsg: 'removeStorage:ok' } - webHandleSuccess(res, success, complete) + successHandle(res, success, complete) } catch (err) { const res = { errMsg: `removeStorage:fail ${err}` } - webHandleFail(res, fail, complete) + failHandle(res, fail, complete) } } @@ -144,10 +143,10 @@ function clearStorage (options = {}) { clearStorageSync() const res = { errMsg: 'clearStorage:ok' } - webHandleSuccess(res, success, complete) + successHandle(res, success, complete) } catch (err) { const res = { errMsg: `clearStorage:fail ${err}` } - webHandleFail(res, fail, complete) + failHandle(res, fail, complete) } } diff --git a/packages/api-proxy/src/platform/api/storage/rnStorage.js b/packages/api-proxy/src/platform/api/storage/rnStorage.js index 8ac6b60255..9e04523984 100644 --- a/packages/api-proxy/src/platform/api/storage/rnStorage.js +++ b/packages/api-proxy/src/platform/api/storage/rnStorage.js @@ -1,6 +1,6 @@ import AsyncStorage from '@react-native-async-storage/async-storage' +import { envError, successHandle, failHandle, defineUnsupportedProps } from '../../../common/js' import { hasOwn } from '@mpxjs/utils' -import { envError, webHandleSuccess, webHandleFail, defineUnsupportedProps } from '../../../common/js' function setStorage (options) { const { key, data, success, fail, complete } = options let obj = {} @@ -14,13 +14,13 @@ function setStorage (options) { const result = { errMsg: `setStorage:fail ${err}` } - webHandleFail(result, fail, complete) + failHandle(result, fail, complete) return } const result = { errMsg: 'setStorage:ok' } - webHandleSuccess(result, success, complete) + successHandle(result, success, complete) }) } @@ -32,7 +32,7 @@ function getStorage (options) { const result = { errMsg: 'getStorage:fail parameter error: parameter.key should be String instead of Undefined;' } - webHandleFail(result, fail, complete) + failHandle(result, fail, complete) return } AsyncStorage.getItem(key, (err, res) => { @@ -40,7 +40,7 @@ function getStorage (options) { const result = { errMsg: `getStorage:fail ${err || 'data not found'}` } - webHandleFail(result, fail, complete) + failHandle(result, fail, complete) return } let item @@ -56,7 +56,7 @@ function getStorage (options) { errMsg: 'getStorage:ok', data } - webHandleSuccess(result, success, complete) + successHandle(result, success, complete) }) } @@ -69,7 +69,7 @@ function getStorageInfo (options) { const result = { errMsg: `getStorage:fail ${err}` } - webHandleFail(result, fail, complete) + failHandle(result, fail, complete) return } const result = { @@ -77,7 +77,7 @@ function getStorageInfo (options) { errMsg: 'getStorageInfo:ok' } defineUnsupportedProps(result, ['currentSize', 'limitSize']) - webHandleSuccess(result, success, complete) + successHandle(result, success, complete) }) } @@ -90,13 +90,13 @@ function removeStorage (options) { const result = { errMsg: `removeStorage:fail ${err}` } - webHandleFail(result, fail, complete) + failHandle(result, fail, complete) return } const result = { errMsg: 'removeStorage:ok' } - webHandleSuccess(result, success, complete) + successHandle(result, success, complete) }) } @@ -111,13 +111,13 @@ function clearStorage (options) { const result = { errMsg: `clearStorage:fail ${err}` } - webHandleFail(result, fail, complete) + failHandle(result, fail, complete) return } const result = { errMsg: 'clearStorage:ok' } - webHandleSuccess(result, success, complete) + successHandle(result, success, complete) }) } diff --git a/packages/api-proxy/src/platform/api/system/index.web.js b/packages/api-proxy/src/platform/api/system/index.web.js index 88baeea109..8d995ddcc3 100644 --- a/packages/api-proxy/src/platform/api/system/index.web.js +++ b/packages/api-proxy/src/platform/api/system/index.web.js @@ -1,4 +1,4 @@ -import { envError, isBrowser, throwSSRWarning, webHandleSuccess } from '../../../common/js' +import { envError, isBrowser, throwSSRWarning, successHandle } from '../../../common/js' function getSystemInfoSync () { if (!isBrowser) { @@ -76,7 +76,7 @@ function getSystemInfo (options = {}) { } const info = getSystemInfoSync() const res = Object.assign({ errMsg: 'getSystemInfo:ok' }, info) - webHandleSuccess(res, options.success, options.complete) + successHandle(res, options.success, options.complete) } const getDeviceInfo = envError('getDeviceInfo') diff --git a/packages/api-proxy/src/platform/api/system/rnSystem.js b/packages/api-proxy/src/platform/api/system/rnSystem.js index ab5f62aef1..f4d635f174 100644 --- a/packages/api-proxy/src/platform/api/system/rnSystem.js +++ b/packages/api-proxy/src/platform/api/system/rnSystem.js @@ -1,7 +1,7 @@ import DeviceInfo from 'react-native-device-info' import { Platform, PixelRatio, Dimensions, StatusBar } from 'react-native' import { initialWindowMetrics } from 'react-native-safe-area-context' -import { webHandleSuccess, webHandleFail, defineUnsupportedProps } from '../../../common/js' +import { successHandle, failHandle, defineUnsupportedProps } from '../../../common/js' const getWindowInfo = function () { const dimensionsWindow = Dimensions.get('window') @@ -84,12 +84,12 @@ const getSystemInfo = function (options) { Object.assign(systemInfo, { errMsg: 'setStorage:ok' }) - webHandleSuccess(systemInfo, success, complete) + successHandle(systemInfo, success, complete) } catch (err) { const result = { errMsg: `getSystemInfo:fail ${err}` } - webHandleFail(result, fail, complete) + failHandle(result, fail, complete) } } diff --git a/packages/api-proxy/src/platform/api/tab-bar/index.web.js b/packages/api-proxy/src/platform/api/tab-bar/index.web.js index 0493f94c85..add213c535 100644 --- a/packages/api-proxy/src/platform/api/tab-bar/index.web.js +++ b/packages/api-proxy/src/platform/api/tab-bar/index.web.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, webHandleFail } from '../../../common/js' +import { successHandle, failHandle } from '../../../common/js' import { hasOwn } from '@mpxjs/utils' import Vue from 'vue' @@ -21,9 +21,9 @@ function setTabBarStyle (options = {}) { } if (resolved) { - webHandleSuccess(resolved, options.success, options.complete) + successHandle(resolved, options.success, options.complete) } - webHandleFail(rejected, options.fail, options.complete) + failHandle(rejected, options.fail, options.complete) } function setTabBarItem (options = {}) { @@ -50,9 +50,9 @@ function setTabBarItem (options = {}) { } if (resolved) { - webHandleSuccess(resolved, options.success, options.complete) + successHandle(resolved, options.success, options.complete) } - webHandleFail(rejected, options.fail, options.complete) + failHandle(rejected, options.fail, options.complete) } function showTabBar (options = {}) { @@ -66,9 +66,9 @@ function showTabBar (options = {}) { } if (resolved) { - webHandleSuccess(resolved, options.success, options.complete) + successHandle(resolved, options.success, options.complete) } - webHandleFail(rejected, options.fail, options.complete) + failHandle(rejected, options.fail, options.complete) } function hideTabBar (options = {}) { @@ -82,9 +82,9 @@ function hideTabBar (options = {}) { } if (resolved) { - webHandleSuccess(resolved, options.success, options.complete) + successHandle(resolved, options.success, options.complete) } - webHandleFail(rejected, options.fail, options.complete) + failHandle(rejected, options.fail, options.complete) } export { diff --git a/packages/api-proxy/src/platform/api/toast/Toast.js b/packages/api-proxy/src/platform/api/toast/Toast.js index 4b1f5f8c2c..df985c7c65 100644 --- a/packages/api-proxy/src/platform/api/toast/Toast.js +++ b/packages/api-proxy/src/platform/api/toast/Toast.js @@ -1,4 +1,4 @@ -import { webHandleSuccess, createDom, getRootElement } from '../../../common/js' +import { successHandle, createDom, getRootElement } from '../../../common/js' import '../../../common/stylus/Toast.styl' import '../../../common/stylus/Loading.styl' @@ -74,7 +74,7 @@ export default class Toast { opts.duration >= 0 && this.hide({ duration: opts.duration }, type) const errMsg = type === 'loading' ? 'showLoading:ok' : 'showToast:ok' - webHandleSuccess({ errMsg }, opts.success, opts.complete) + successHandle({ errMsg }, opts.success, opts.complete) } hide (options = {}, type) { @@ -82,7 +82,7 @@ export default class Toast { const duration = options.duration || 0 const errMsg = type === 'loading' ? 'hideLoading:ok' : 'hideToast:ok' - webHandleSuccess({ errMsg }, options.success, options.complete) + successHandle({ errMsg }, options.success, options.complete) if (this.hideTimer) { clearTimeout(this.hideTimer) diff --git a/packages/api-proxy/src/platform/api/toast/error.png b/packages/api-proxy/src/platform/api/toast/error.png new file mode 100644 index 0000000000..6f54a262a1 Binary files /dev/null and b/packages/api-proxy/src/platform/api/toast/error.png differ diff --git a/packages/api-proxy/src/platform/api/toast/index.android.js b/packages/api-proxy/src/platform/api/toast/index.android.js new file mode 100644 index 0000000000..fce6791294 --- /dev/null +++ b/packages/api-proxy/src/platform/api/toast/index.android.js @@ -0,0 +1 @@ +export * from './rnToast' diff --git a/packages/api-proxy/src/platform/api/toast/index.ios.js b/packages/api-proxy/src/platform/api/toast/index.ios.js new file mode 100644 index 0000000000..fce6791294 --- /dev/null +++ b/packages/api-proxy/src/platform/api/toast/index.ios.js @@ -0,0 +1 @@ +export * from './rnToast' diff --git a/packages/api-proxy/src/platform/api/toast/rnToast.jsx b/packages/api-proxy/src/platform/api/toast/rnToast.jsx new file mode 100644 index 0000000000..a9f7648d42 --- /dev/null +++ b/packages/api-proxy/src/platform/api/toast/rnToast.jsx @@ -0,0 +1,189 @@ +import { View, Text, Image, StyleSheet, ActivityIndicator } from 'react-native' +import { successHandle, failHandle } from '../../../common/js' +import { Portal } from '@ant-design/react-native' +import successPng from './success.png' +import errorPng from './error.png' + +let toastKey +let isLoadingShow +let tId // show duration 计时id +const styles = StyleSheet.create({ + toastContent: { + minWdth: 150, + maxWidth: '60%', + backgroundColor: 'rgba(20, 20, 20, 0.7)', + paddingTop: 15, + paddingBottom: 15, + paddingLeft: 20, + paddingRight: 20, + borderRadius: 5, + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center' + }, + toastWrap: { + left: 0, + right: 0, + top: 0, + bottom: 0, + zIndex: 10000, + position: "absolute", + display: 'flex', + justifyContent: 'center', + alignItems: 'center' + }, + toastImg: { + width: 40, + height: 40, + marginLeft: 'auto', + marginRight: 'auto', + marginBottom: 10 + }, + toastText: { + textAlign: 'center', + color: '#ffffff', + fontSize: 14, + lineHeight: 18, + height: 18, + overflow: 'hidden' + } +}) +function showToast (options) { + const { title, icon = 'success', image, duration = 1500, mask = false, success, fail, complete, isLoading } = options + let ToastView + const iconImg = { + success: successPng, + fail: errorPng + } + const pointerEvents = mask ? 'auto' : 'none' + isLoadingShow = isLoading + if (tId) { + clearTimeout(tId) + } + tId = null + if (image || icon === 'success' || icon === 'error') { + ToastView = + + + {title} + + + } else if (icon === 'loading') { + ToastView = + + + {title} + + + } else { + ToastView = + + {title} + + + } + try { + if (toastKey) { + Portal.remove(toastKey) + } + toastKey = Portal.add(ToastView) + if (!isLoading) { + tId = setTimeout(() => { + Portal.remove(toastKey) + toastKey = null + }, duration) + } + const result = { + errMsg: 'showToast:ok' + } + successHandle(result, success, complete) + } catch (e) { + const result = { + errMsg: `showToast:fail invalid ${e}` + } + failHandle(result, fail, complete) + } +} + +function hideToast(options) { + const { noConflict = false, success, fail, complete } = options + + if (isLoadingShow && noConflict) { + return + } + try { + if (toastKey) { + Portal.remove(toastKey) + toastKey = null + } + const result = { + errMsg: 'hideToast:ok' + } + successHandle(result, success, complete) + } catch (e) { + const result = { + errMsg: `hideToast:fail invalid ${e}` + } + failHandle(result, fail, complete) + } +} + +function showLoading (options) { + const { title, mask, success, fail, complete } = options + showToast({ + title, + mask, + icon: 'loading', + isLoading: true, + success () { + const result = { + errMsg: 'showLoading:ok' + } + successHandle(result, success, complete) + }, + fail (res) { + const result = { + errMsg: res.errMsg.replace('showToast', 'showLoading') + } + failHandle(result, success, complete) + } + }) +} + +function hideLoading (options) { + const { noConflict = false, success, fail, complete } = options + if (!isLoadingShow && noConflict) { + return + } + isLoadingShow = false + try { + if (toastKey) { + Portal.remove(toastKey) + toastKey = null + } + const result = { + errMsg: 'hideLoading:ok' + } + successHandle(result, success, complete) + } catch (e) { + const result = { + errMsg: `hideLoading:fail invalid ${e}` + } + failHandle(result, fail, complete) + } +} + +export { + showToast, + hideToast, + showLoading, + hideLoading +} diff --git a/packages/api-proxy/src/platform/api/toast/success.png b/packages/api-proxy/src/platform/api/toast/success.png new file mode 100644 index 0000000000..9da287c320 Binary files /dev/null and b/packages/api-proxy/src/platform/api/toast/success.png differ diff --git a/packages/api-proxy/src/platform/index.js b/packages/api-proxy/src/platform/index.js index 8fd53cbcb1..86c8f5c955 100644 --- a/packages/api-proxy/src/platform/index.js +++ b/packages/api-proxy/src/platform/index.js @@ -107,3 +107,6 @@ export * from './api/window' // getEnterOptionsSync export * from './api/lifecycle' + +// getLocation, openLocation, chooseLocation +export * from './api/location' diff --git a/packages/core/package.json b/packages/core/package.json index aa34647436..039349b9c2 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@mpxjs/core", - "version": "2.9.50", + "version": "2.9.57", "description": "mpx runtime core", "keywords": [ "miniprogram", diff --git a/packages/core/src/convertor/wxToAli.js b/packages/core/src/convertor/wxToAli.js index 12271cf775..d47c372950 100644 --- a/packages/core/src/convertor/wxToAli.js +++ b/packages/core/src/convertor/wxToAli.js @@ -1,7 +1,6 @@ import * as wxLifecycle from '../platform/patch/wx/lifecycle' import * as aliLifecycle from '../platform/patch/ali/lifecycle' import { mergeLifecycle } from './mergeLifecycle' -import { mergeToArray } from '../core/mergeOptions' import { error, hasOwn, isDev } from '@mpxjs/utils' import { implemented } from '../core/implement' @@ -60,14 +59,6 @@ export default { options.props = props delete options.properties } - if (options.onResize) { - mergeToArray(options, { - events: { - onResize: options.onResize - } - }, 'events') - delete options.onResize - } notSupportTip(options) } } diff --git a/packages/core/src/platform/builtInMixins/pageStatusMixin.web.js b/packages/core/src/platform/builtInMixins/pageStatusMixin.web.js index a52b8418e6..18a0c395ad 100644 --- a/packages/core/src/platform/builtInMixins/pageStatusMixin.web.js +++ b/packages/core/src/platform/builtInMixins/pageStatusMixin.web.js @@ -3,7 +3,8 @@ import { CREATED, ONHIDE, ONSHOW, - ONLOAD + ONLOAD, + ONRESIZE } from '../../core/innerLifecycle' import { isFunction, isBrowser } from '@mpxjs/utils' @@ -35,11 +36,11 @@ function onResize () { } } - const _t = getCurrentPageInstance() + const pageInstance = getCurrentPageInstance() - if (_t) { - _t.mpxPageStatus = `resize${count++}` - isFunction(_t.onResize) && _t.onResize(systemInfo) + if (pageInstance) { + pageInstance.mpxPageStatus = `resize${count++}` + pageInstance.__mpxProxy.callHook(ONRESIZE, [systemInfo]) } } diff --git a/packages/core/src/platform/builtInMixins/proxyEventMixin.ios.js b/packages/core/src/platform/builtInMixins/proxyEventMixin.ios.js index 3d6fb784e8..bf277b3e9c 100644 --- a/packages/core/src/platform/builtInMixins/proxyEventMixin.ios.js +++ b/packages/core/src/platform/builtInMixins/proxyEventMixin.ios.js @@ -1,4 +1,4 @@ -import { error } from '@mpxjs/utils' +import { error, setByPath } from '@mpxjs/utils' import Mpx from '../../index' export default function proxyEventMixin () { @@ -33,15 +33,15 @@ export default function proxyEventMixin () { } }) return returnedValue + }, + __model (expr, $event, valuePath = ['value'], filterMethod) { + const innerFilter = { + trim: val => typeof val === 'string' && val.trim() + } + const originValue = valuePath.reduce((acc, cur) => acc[cur], $event.detail) + const value = filterMethod ? (innerFilter[filterMethod] ? innerFilter[filterMethod](originValue) : typeof this[filterMethod] === 'function' ? this[filterMethod](originValue) : originValue) : originValue + setByPath(this, expr, value) } - // __model (expr, $event, valuePath = ['value'], filterMethod) { - // const innerFilter = { - // trim: val => typeof val === 'string' && val.trim() - // } - // const originValue = valuePath.reduce((acc, cur) => acc[cur], $event.detail) - // const value = filterMethod ? (innerFilter[filterMethod] ? innerFilter[filterMethod](originValue) : typeof this[filterMethod] === 'function' ? this[filterMethod](originValue) : originValue) : originValue - // setByPath(this, expr, value) - // } } return { methods diff --git a/packages/core/src/platform/createApp.ios.js b/packages/core/src/platform/createApp.ios.js index cd80d2e6f6..f4e878ed6a 100644 --- a/packages/core/src/platform/createApp.ios.js +++ b/packages/core/src/platform/createApp.ios.js @@ -39,6 +39,10 @@ export default function createApp (option, config = {}) { const { rawOptions, currentInject } = transferOptions(option, 'app', false) const defaultOptions = filterOptions(spreadProp(rawOptions, 'methods'), appData) defaultOptions.onAppInit && defaultOptions.onAppInit() + // 在页面script执行前填充getApp() + global.getApp = function () { + return appData + } const pages = currentInject.getPages() || {} const firstPage = currentInject.firstPage const Stack = createNativeStackNavigator() @@ -96,9 +100,7 @@ export default function createApp (option, config = {}) { ) ) }) - global.getApp = function () { - return appData - } + global.getCurrentPages = function () { const navigation = Object.values(global.__mpxPagesMap || {})[0]?.[1] if (navigation) { diff --git a/packages/core/src/platform/export/api.js b/packages/core/src/platform/export/api.js index ee9d81151b..325653cc21 100644 --- a/packages/core/src/platform/export/api.js +++ b/packages/core/src/platform/export/api.js @@ -1,4 +1,5 @@ -import { set, del, reactive } from '../../observer/reactive' +import { set, del, reactive, isReactive } from '../../observer/reactive' +import { isRef } from '../../observer/ref' import { watch } from '../../observer/watch' import { injectMixins } from '../../core/injectMixins' @@ -8,7 +9,9 @@ const APIs = { observable: reactive, watch, set, - delete: del + delete: del, + isReactive, + isRef } const InstanceAPIs = { diff --git a/packages/core/src/platform/export/api.web.js b/packages/core/src/platform/export/api.web.js index f6880c9da3..0601010647 100644 --- a/packages/core/src/platform/export/api.web.js +++ b/packages/core/src/platform/export/api.web.js @@ -1,19 +1,22 @@ -import Vue from 'vue' +import { + watch, + reactive, + isReactive, + set, + del, + isRef +} from 'vue' import { injectMixins } from '../../core/injectMixins' -const vm = new Vue() -const observable = Vue.observable.bind(Vue) -const watch = vm.$watch.bind(vm) -const set = Vue.set.bind(Vue) -const del = Vue.delete.bind(Vue) - const APIs = { injectMixins, mixin: injectMixins, - observable, + observable: reactive, watch, set, - delete: del + delete: del, + isReactive, + isRef } const InstanceAPIs = {} diff --git a/packages/core/src/platform/patch/ali/getDefaultOptions.js b/packages/core/src/platform/patch/ali/getDefaultOptions.js index 1d49564fdb..33120e53d5 100644 --- a/packages/core/src/platform/patch/ali/getDefaultOptions.js +++ b/packages/core/src/platform/patch/ali/getDefaultOptions.js @@ -1,7 +1,7 @@ import MpxProxy from '../../../core/proxy' import builtInKeysMap from '../builtInKeysMap' import mergeOptions from '../../../core/mergeOptions' -import { isFunction, error, diffAndCloneA, hasOwn, noop } from '@mpxjs/utils' +import { error, diffAndCloneA, hasOwn, noop } from '@mpxjs/utils' function transformApiForProxy (context, currentInject) { const rawSetData = context.setData.bind(context) @@ -23,7 +23,7 @@ function transformApiForProxy (context, currentInject) { const validProps = Object.assign({}, options.properties, options.props) if (context.props) { Object.keys(context.props).forEach((key) => { - if (hasOwn(validProps, key) && !isFunction(context.props[key])) { + if (hasOwn(validProps, key)) { props[key] = context.props[key] } }) @@ -129,7 +129,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { if (rawOptions.__nativeRender__ && this.props) { const validProps = Object.assign({}, rawOptions.props, rawOptions.properties) Object.keys(this.props).forEach((key) => { - if (hasOwn(validProps, key) && !isFunction(this.props[key])) { + if (hasOwn(validProps, key)) { this.data[key] = this.props[key] } }) @@ -143,7 +143,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { const newData = {} // 微信原生转换支付宝时,每次props更新将其设置进data模拟微信表现 Object.keys(nextProps).forEach((key) => { - if (hasOwn(validProps, key) && !isFunction(nextProps[key])) { + if (hasOwn(validProps, key)) { const { diff, clone } = diffAndCloneA(nextProps[key], this.props[key]) if (diff) newData[key] = clone } @@ -153,7 +153,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { // 由于支付宝中props透传父级setData的值,此处发生变化的属性实例一定不同,只需浅比较即可确定发生变化的属性 // 支付宝appx2.0版本后props传递发生变化,此处获取到的nextProps和this.props以及父组件setData的数据引用都不一致,进行了两次深克隆,此处this.props和nextProps的比对需要用deep diff Object.keys(nextProps).forEach(key => { - if (hasOwn(validProps, key) && !isFunction(nextProps[key])) { + if (hasOwn(validProps, key)) { const { diff, clone } = diffAndCloneA(nextProps[key], this.props[key]) // 由于支付宝中透传父级setData的值,此处进行深clone后赋值避免父级存储的miniRenderData部分数据在此处被响应化,在子组件对props赋值时触发父组件的render if (diff) this[key] = clone diff --git a/packages/core/src/platform/patch/react/getDefaultOptions.ios.js b/packages/core/src/platform/patch/react/getDefaultOptions.ios.js index 4121254701..7e074593af 100644 --- a/packages/core/src/platform/patch/react/getDefaultOptions.ios.js +++ b/packages/core/src/platform/patch/react/getDefaultOptions.ios.js @@ -52,13 +52,20 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps __getProps () { const propsData = {} const props = propsRef.current - if (props) { - Object.keys(props).forEach((key) => { - if (hasOwn(validProps, key) && !isFunction(props[key])) { - propsData[key] = props[key] + Object.keys(validProps).forEach((key) => { + if (hasOwn(props, key)) { + propsData[key] = props[key] + } else { + let field = validProps[key] + if (isFunction(field) || field === null) { + field = { + type: field + } } - }) - } + // 处理props默认值 + propsData[key] = field.value + } + }) return propsData }, __getSlot (name) { @@ -233,7 +240,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { // 处理props更新 propsRef.current = props Object.keys(props).forEach(key => { - if (hasOwn(validProps, key) && !isFunction(props[key])) { + if (hasOwn(validProps, key)) { instance[key] = props[key] } }) diff --git a/packages/core/src/platform/patch/swan/lifecycle.js b/packages/core/src/platform/patch/swan/lifecycle.js index 5a8e18a758..eb7f3bffd5 100644 --- a/packages/core/src/platform/patch/swan/lifecycle.js +++ b/packages/core/src/platform/patch/swan/lifecycle.js @@ -4,7 +4,8 @@ import { MOUNTED, ONSHOW, ONHIDE, - ONLOAD + ONLOAD, + ONRESIZE } from '../../../core/innerLifecycle' const APP_HOOKS = [ @@ -47,7 +48,8 @@ export const lifecycleProxyMap = { [UNMOUNTED]: ['detached', 'onUnload'], [ONSHOW]: ['pageShow', 'onShow'], [ONHIDE]: ['pageHide', 'onHide'], - [ONLOAD]: ['onLoad'] + [ONLOAD]: ['onLoad'], + [ONRESIZE]: ['onResize'] } export const LIFECYCLE = { diff --git a/packages/core/src/platform/patch/wx/getDefaultOptions.js b/packages/core/src/platform/patch/wx/getDefaultOptions.js index 7d7883785d..dd8d5cf0a6 100644 --- a/packages/core/src/platform/patch/wx/getDefaultOptions.js +++ b/packages/core/src/platform/patch/wx/getDefaultOptions.js @@ -1,4 +1,4 @@ -import { hasOwn, noop } from '@mpxjs/utils' +import { hasOwn, noop, isFunction } from '@mpxjs/utils' import MpxProxy from '../../../core/proxy' import builtInKeysMap from '../builtInKeysMap' import mergeOptions from '../../../core/mergeOptions' @@ -16,7 +16,7 @@ function transformProperties (properties) { type: null } } - if (typeof rawFiled === 'function') { + if (isFunction(rawFiled)) { newFiled = { type: rawFiled } diff --git a/packages/core/src/platform/patch/wx/lifecycle.js b/packages/core/src/platform/patch/wx/lifecycle.js index 02878e5461..2e6fe7f01d 100644 --- a/packages/core/src/platform/patch/wx/lifecycle.js +++ b/packages/core/src/platform/patch/wx/lifecycle.js @@ -4,7 +4,8 @@ import { MOUNTED, ONSHOW, ONHIDE, - ONLOAD + ONLOAD, + ONRESIZE } from '../../../core/innerLifecycle' const APP_HOOKS = [ @@ -52,7 +53,8 @@ export const lifecycleProxyMap = { [UNMOUNTED]: ['detached', 'onUnload'], [ONSHOW]: ['pageShow', 'onShow'], [ONHIDE]: ['pageHide', 'onHide'], - [ONLOAD]: ['onLoad'] + [ONLOAD]: ['onLoad'], + [ONRESIZE]: ['onResize'] } export const LIFECYCLE = { diff --git a/packages/utils/src/object.js b/packages/utils/src/object.js index edb3c45103..dcc797d1db 100644 --- a/packages/utils/src/object.js +++ b/packages/utils/src/object.js @@ -1,4 +1,3 @@ -import { isRef, isReactive } from '@mpxjs/core' import { type, noop } from './base' const hasOwnProperty = Object.prototype.hasOwnProperty @@ -113,12 +112,19 @@ function diffAndCloneA (a, b) { } function proxy (target, source, keys, readonly, onConflict) { + if (!global.__mpx) { + console.warn('[Mpx utils warn]: Can not find "global.__mpx", "proxy" may encounter some potential problems!') + } keys = keys || Object.keys(source) keys.forEach((key) => { const descriptor = { get () { const val = source[key] - return !isReactive(source) && isRef(val) ? val.value : val + if (global.__mpx) { + return !global.__mpx.isReactive(source) && global.__mpx.isRef(val) ? val.value : val + } else { + return val + } }, configurable: true, enumerable: true @@ -126,12 +132,15 @@ function proxy (target, source, keys, readonly, onConflict) { descriptor.set = readonly ? noop : function (val) { - // 对reactive对象代理时不需要处理ref解包 - if (!isReactive(source)) { - const oldVal = source[key] - if (isRef(oldVal) && !isRef(val)) { - oldVal.value = val - return + if (global.__mpx) { + const isRef = global.__mpx.isRef + // 对reactive对象代理时不需要处理ref解包 + if (!global.__mpx.isReactive(source)) { + const oldVal = source[key] + if (isRef(oldVal) && !isRef(val)) { + oldVal.value = val + return + } } } source[key] = val diff --git a/packages/utils/src/path.js b/packages/utils/src/path.js index 59474cecb9..c99bb0478e 100644 --- a/packages/utils/src/path.js +++ b/packages/utils/src/path.js @@ -1,5 +1,3 @@ -import { set } from '@mpxjs/core' - let curStack let targetStacks let property @@ -155,9 +153,16 @@ function getByPath (data, pathStrOrArr, defaultVal, errTip) { } function setByPath (data, pathStrOrArr, value) { + if (!global.__mpx) { + console.warn('[Mpx utils warn]: Can not find "global.__mpx", "setByPath" may encounter some potential problems!') + } doGetByPath(data, pathStrOrArr, (current, key, meta) => { if (meta.isEnd) { - set(current, key, value) + if (global.__mpx) { + global.__mpx.set(current, key, value) + } else { + current[key] = value + } } else if (!current[key]) { current[key] = {} } diff --git a/packages/webpack-plugin/lib/json-compiler/index.js b/packages/webpack-plugin/lib/json-compiler/index.js index 9178d22f21..f0386554a9 100644 --- a/packages/webpack-plugin/lib/json-compiler/index.js +++ b/packages/webpack-plugin/lib/json-compiler/index.js @@ -706,7 +706,8 @@ module.exports = function (content) { for (const root in subPackagesCfg) { const subPackageCfg = subPackagesCfg[root] // 分包不存在 pages,输出 subPackages 字段会报错 - if (subPackageCfg.pages.length) { + // tt模式下分包异步允许一个分包不存在 pages + if (subPackageCfg.pages.length || mode === 'tt') { if (!json.subPackages) { json.subPackages = [] } diff --git a/packages/webpack-plugin/lib/platform/json/wx/index.js b/packages/webpack-plugin/lib/platform/json/wx/index.js index bae604cb18..2562b9ff44 100644 --- a/packages/webpack-plugin/lib/platform/json/wx/index.js +++ b/packages/webpack-plugin/lib/platform/json/wx/index.js @@ -153,7 +153,6 @@ module.exports = function getSpec ({ warn, error }) { test: 'componentPlaceholder', ali: aliComponentPlaceholderFallback, swan: deletePath(), - tt: deletePath(), jd: deletePath() }, { diff --git a/packages/webpack-plugin/lib/platform/template/wx/component-config/web-view.js b/packages/webpack-plugin/lib/platform/template/wx/component-config/web-view.js index 815cbc9819..5dee3d7b20 100644 --- a/packages/webpack-plugin/lib/platform/template/wx/component-config/web-view.js +++ b/packages/webpack-plugin/lib/platform/template/wx/component-config/web-view.js @@ -6,6 +6,14 @@ module.exports = function () { web (tag, { el }) { el.isBuiltIn = true return 'mpx-web-view' + }, + ios (tag, { el }) { + el.isBuiltIn = true + return 'mpx-web-view' + }, + android (tag, { el }) { + el.isBuiltIn = true + return 'mpx-web-view' } } } diff --git a/packages/webpack-plugin/lib/react/index.js b/packages/webpack-plugin/lib/react/index.js index 20506cdb7a..a7e9e34a2d 100644 --- a/packages/webpack-plugin/lib/react/index.js +++ b/packages/webpack-plugin/lib/react/index.js @@ -57,7 +57,6 @@ module.exports = function ({ (callback) => { processStyles(parts.styles, { loaderContext, - srcMode, ctorType, autoScope, moduleId diff --git a/packages/webpack-plugin/lib/react/processStyles.js b/packages/webpack-plugin/lib/react/processStyles.js index 54af3dd988..f07e6b79f2 100644 --- a/packages/webpack-plugin/lib/react/processStyles.js +++ b/packages/webpack-plugin/lib/react/processStyles.js @@ -5,7 +5,6 @@ const shallowStringify = require('../utils/shallow-stringify') module.exports = function (styles, { loaderContext, - srcMode, ctorType, autoScope, moduleId @@ -14,7 +13,17 @@ module.exports = function (styles, { let content = '' let output = '/* styles */\n' if (styles.length) { - const { mode } = loaderContext.getMpx() + const warn = (msg) => { + loaderContext.emitWarning( + new Error('[style compiler][' + loaderContext.resource + ']: ' + msg) + ) + } + const error = (msg) => { + loaderContext.emitError( + new Error('[style compiler][' + loaderContext.resource + ']: ' + msg) + ) + } + const { mode, srcMode } = loaderContext.getMpx() async.eachOfSeries(styles, (style, i, callback) => { const scoped = style.scoped || autoScope const extraOptions = { @@ -41,7 +50,9 @@ module.exports = function (styles, { content, filename: loaderContext.resourcePath, mode, - srcMode + srcMode, + warn, + error }) if (ctorType === 'app') { output += `global.__getAppClassMap = function() { diff --git a/packages/webpack-plugin/lib/react/style-helper.js b/packages/webpack-plugin/lib/react/style-helper.js index 58f556c5df..f684d1b572 100644 --- a/packages/webpack-plugin/lib/react/style-helper.js +++ b/packages/webpack-plugin/lib/react/style-helper.js @@ -5,7 +5,7 @@ const dash2hump = require('../utils/hump-dash').dash2hump const rpxRegExp = /^\s*(\d+(\.\d+)?)rpx\s*$/ const pxRegExp = /^\s*(\d+(\.\d+)?)(px)?\s*$/ const cssPrefixExp = /^-(webkit|moz|ms|o)-/ -function getClassMap ({ content, filename, mode, srcMode }) { +function getClassMap ({ content, filename, mode, srcMode, warn, error }) { const classMap = {} const root = postcss.parse(content, { @@ -30,12 +30,8 @@ function getClassMap ({ content, filename, mode, srcMode }) { srcMode, type: 'style', testKey: 'prop', - warn: (msg) => { - console.warn('[style compiler warn]: ' + msg) - }, - error: (msg) => { - console.error('[style compiler error]: ' + msg) - } + warn, + error }) root.walkRules(rule => { @@ -70,7 +66,7 @@ function getClassMap ({ content, filename, mode, srcMode }) { if (selector.nodes.length === 1 && selector.nodes[0].type === 'class') { classMapKeys.push(selector.nodes[0].value) } else { - rule.error('Only single class selector is supported in react native mode temporarily.') + error('Only single class selector is supported in react native mode temporarily.') } }) }).processSync(rule.selector) diff --git a/packages/webpack-plugin/lib/runtime/base.styl b/packages/webpack-plugin/lib/runtime/base.styl index cc60399942..a69f4e3714 100644 --- a/packages/webpack-plugin/lib/runtime/base.styl +++ b/packages/webpack-plugin/lib/runtime/base.styl @@ -128,3 +128,30 @@ page { font-family "weui" src url('data:application/octet-stream;base64,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') format('truetype') } + +.mpx-slide-left-enter { + transform: translateX(100%) +} +.mpx-slide-left-enter-active { + transition: transform 0.3s; + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; + z-index: 100; +} +.mpx-slide-left-leave-active { + transition: transform 0.2s +} + +.mpx-slide-right-leave-active { + position: absolute; + z-index: 100; + top: 0; + right: 0; + left: 0; + bottom: 0; + transform: translateX(100%); + transition: transform 0.3s +} diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 1d2d1db1f0..0e0361200e 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -11,7 +11,7 @@ import { DataSetType, LayoutRef, NativeTouchEvent -} from './getInnerListeners.type' +} from './types/getInnerListeners' const getTouchEvent = ( type: string, diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-button.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-button.tsx index eb102eb50b..a3e537651e 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-button.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-button.tsx @@ -331,14 +331,13 @@ const Button = forwardRef,ButtonProps >((props, r const catchTap = (evt: NativeSyntheticEvent) => { if (disabled) return catchtap && catchtap(getCustomEvent('tap', evt, { layoutRef }, props)) - handleOpenTypeEvent(evt) } function wrapChildren(children: ReactNode, textStyle?: StyleProp) { if (every(children, (child)=>isText(child))) { children = [{children}] } else { - if(textStyle) console.warn('Text style will be ignored unless every child of the button is Text node!') + if(textStyle) console.warn('Text style will be ignored unless every child of the Button is Text node!') } return children diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-image/svg.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-image/svg.tsx index dd52f38392..ed236ea512 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-image/svg.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-image/svg.tsx @@ -1,7 +1,6 @@ import React from 'react' import type { ImageSourcePropType, ImageStyle, StyleProp } from 'react-native' import { SvgCssUri, WithLocalSvg } from 'react-native-svg/css' - interface SvgProps { local?: boolean src: string | ImageSourcePropType diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx new file mode 100644 index 0000000000..443446c4f7 --- /dev/null +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-web-view.tsx @@ -0,0 +1,171 @@ +import { forwardRef, JSX, useRef, useEffect } from 'react' +// @ts-ignore +import { noop } from '@mpxjs/utils' +import { Portal } from '@ant-design/react-native' +import { getCustomEvent } from './getInnerListeners' +import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy' +// @ts-ignore +import { WebView } from 'react-native-webview' +import useNodesRef, { HandlerRef } from './useNodesRef' +import { StyleSheet } from 'react-native' + +type OnMessageCallbackEvent = { + detail: { + data: any[] + } +} + +type CommonCallbackEvent = { + detail: { + src?: string + } +} + +interface WebViewProps { + src: string + bindmessage?: (event: OnMessageCallbackEvent) => void + bindload?: (event: CommonCallbackEvent) => void + binderror?: (event: CommonCallbackEvent) => void +} + +interface PayloadData { + data?: Record +} + +type MessageData = { + payload?: PayloadData, + type?: string, + callbackId?: number +} + +interface NativeEvent { + url: string, + data: string +} + +interface LoadRes { + timeStamp: string, + nativeEvent: NativeEvent +} + +interface FormRef { + postMessage: (value: any) => void; +} + +const _WebView = forwardRef, WebViewProps>((props, ref): JSX.Element => { + const { src, bindmessage = noop, bindload = noop, binderror = noop } = props + + const defaultWebViewStyle = [ + { + position: 'absolute', + left: 0, + right: 0, + top: 0, + bottom: 0 + } + ] + const { nodeRef: webViewRef } = useNodesRef(props, ref, { + defaultStyle: StyleSheet.flatten([ + ...defaultWebViewStyle + ]) + }) + const _messageList:any[] = [] + const handleUnload = () => { + // 这里是 WebView 销毁前执行的逻辑 + bindmessage(getCustomEvent('messsage', {}, { + detail: { + data: _messageList + }, + layoutRef: webViewRef + })) + } + + useEffect(() => { + // 组件卸载时执行 + return () => { + handleUnload() + } + }, []) + const _load = function(res:LoadRes) { + const result = { + type: 'load', + timeStamp: res.timeStamp, + detail: { + src: res.nativeEvent?.url + } + } + bindload(result) + } + const _error = function(res:LoadRes) { + const result = { + type: 'error', + timeStamp: res.timeStamp, + detail: { + src: '' + } + } + binderror(result) + } + const _message = function(res:LoadRes) { + let data: MessageData + let asyncCallback + const navObj = promisify({ redirectTo, navigateTo, navigateBack, reLaunch, switchTab }) + try { + const nativeEventData = res.nativeEvent?.data + data = JSON.parse(nativeEventData) + } catch (e) { + data = {} + } + const postData:PayloadData = data.payload || {} + switch (data.type) { + case 'postMessage': + _messageList.push(postData.data) + asyncCallback = Promise.resolve({ + errMsg: 'invokeWebappApi:ok' + }) + break + case 'navigateTo': + asyncCallback = navObj.navigateTo(postData) + break + case 'navigateBack': + asyncCallback = navObj.navigateBack(postData) + break + case 'redirectTo': + asyncCallback = navObj.redirectTo(postData) + break + case 'switchTab': + asyncCallback = navObj.switchTab(postData) + break + case 'reLaunch': + asyncCallback = navObj.reLaunch(postData) + break + } + + asyncCallback && asyncCallback.then((res: any) => { + if (webViewRef.current?.postMessage) { + const test = JSON.stringify({ + type: data.type, + callbackId: data.callbackId, + result: res + }) + webViewRef.current.postMessage(test) + } + }) + } + // @ts-ignore + return( + + ) +}) + +_WebView.displayName = 'mpx-web-view' + +export default _WebView diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.type.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts similarity index 93% rename from packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.type.ts rename to packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts index 21edaef977..d040a4bce6 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.type.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts @@ -1,7 +1,7 @@ -import React from 'react' +import { MutableRefObject } from 'react' import { NativeSyntheticEvent } from 'react-native' -type LayoutRef = React.MutableRefObject +type LayoutRef = MutableRefObject type SetTimeoutReturnType = ReturnType diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts new file mode 100644 index 0000000000..c0ff600eff --- /dev/null +++ b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts @@ -0,0 +1,15 @@ +declare module 'react-native-svg/css' { + import type { ImageSourcePropType, StyleProp, ImageStyle } from 'react-native' + import type { SvgProps as SvgCssUriProps } from 'react-native-svg' + + export const SvgCssUri: React.ComponentType + + export interface WithLocalSvgProps { + asset: ImageSourcePropType + style?: StyleProp + width?: string | number + height?: string | number + } + + export const WithLocalSvg: React.ComponentType +} \ No newline at end of file diff --git a/packages/webpack-plugin/lib/runtime/optionProcessor.js b/packages/webpack-plugin/lib/runtime/optionProcessor.js index 7a6fd992db..035e539f70 100644 --- a/packages/webpack-plugin/lib/runtime/optionProcessor.js +++ b/packages/webpack-plugin/lib/runtime/optionProcessor.js @@ -75,7 +75,32 @@ registered in parent context!`) if (outputPath) { option.componentPath = '/' + outputPath } + if (ctorType === 'app') { + option.data = function () { + return { + transitionName: '' + } + } + option.watch = { + $route: { + handler () { + const actionType = global.__mpxRouter.currentActionType + switch (actionType) { + case 'to': + this.transitionName = 'mpx-slide-left' + break + case 'back': + this.transitionName = 'mpx-slide-right' + break + default: + this.transitionName = '' + } + }, + immediate: true + } + } + } return option } @@ -160,6 +185,7 @@ function createApp ({ componentsMap, Vue, pagesMap, firstPage, VueRouter, App, t global.__mpxRouter.needCache = null global.__mpxRouter.needRemove = [] global.__mpxRouter.eventChannelMap = {} + global.__mpxRouter.currentActionType = null // 处理reLaunch中传递的url并非首页时的replace逻辑 global.__mpxRouter.beforeEach(function (to, from, next) { let action = global.__mpxRouter.__mpxAction @@ -178,7 +204,7 @@ function createApp ({ componentsMap, Vue, pagesMap, firstPage, VueRouter, App, t } } } - + global.__mpxRouter.currentActionType = action.type const pageInRoutes = routes.some(item => item.path === to.path) if (!pageInRoutes) { if (stack.length < 1) { diff --git a/packages/webpack-plugin/lib/template-compiler/compiler.js b/packages/webpack-plugin/lib/template-compiler/compiler.js index a09d0fb2d7..4d9d4129da 100644 --- a/packages/webpack-plugin/lib/template-compiler/compiler.js +++ b/packages/webpack-plugin/lib/template-compiler/compiler.js @@ -1094,12 +1094,39 @@ function processStyleReact (el) { } } -function processEventReact (el, options, meta) { +function getModelConfig (el, match) { + const modelProp = getAndRemoveAttr(el, config[mode].directive.modelProp).val || config[mode].event.defaultModelProp + const modelEvent = getAndRemoveAttr(el, config[mode].directive.modelEvent).val || config[mode].event.defaultModelEvent + const modelValuePathRaw = getAndRemoveAttr(el, config[mode].directive.modelValuePath).val + const modelValuePath = modelValuePathRaw === undefined ? config[mode].event.defaultModelValuePath : modelValuePathRaw + const modelFilter = getAndRemoveAttr(el, config[mode].directive.modelFilter).val + let modelValuePathArr + try { + modelValuePathArr = JSON5.parse(modelValuePath) + } catch (e) { + if (modelValuePath === '') { + modelValuePathArr = [] + } else { + modelValuePathArr = modelValuePath.split('.') + } + } + const modelValue = match[1].trim() + const stringifiedModelValue = stringifyWithResolveComputed(modelValue) + return { + modelProp, + modelEvent, + modelFilter, + modelValuePathArr, + stringifiedModelValue + } +} + +function processEventReact (el) { const eventConfigMap = {} el.attrsList.forEach(function ({ name, value }) { const parsedEvent = config[mode].event.parseEvent(name) if (parsedEvent) { - const type = parsedEvent.eventName + const type = config[mode].event.getEvent(parsedEvent.eventName, parsedEvent.prefix) const parsedFunc = parseFuncStr(value) if (parsedFunc) { if (!eventConfigMap[type]) { @@ -1112,12 +1139,43 @@ function processEventReact (el, options, meta) { } }) - let wrapper + const modelExp = getAndRemoveAttr(el, config[mode].directive.model).val + if (modelExp) { + const match = tagRE.exec(modelExp) + if (match) { + const { modelProp, modelEvent, modelFilter, modelValuePathArr, stringifiedModelValue } = getModelConfig(el, match) + if (!isValidIdentifierStr(modelEvent)) { + warn$1(`EventName ${modelEvent} which is used in ${config[mode].directive.model} must be a valid identifier!`) + return + } + // if (forScopes.length) { + // stringifiedModelValue = stringifyWithResolveComputed(modelValue) + // } else { + // stringifiedModelValue = stringify(modelValue) + // } + // todo 未来可能需要支持类似modelEventPrefix这样的配置来声明model事件的绑定方式 + const modelEventType = config[mode].event.getEvent(modelEvent) + if (!eventConfigMap[modelEventType]) { + eventConfigMap[modelEventType] = { + configs: [] + } + } + eventConfigMap[modelEventType].configs.unshift({ + hasArgs: true, + expStr: `[${stringify('__model')},${stringifiedModelValue},${stringify(eventIdentifier)},${stringify(modelValuePathArr)}${modelFilter ? `,${stringify(modelFilter)}` : ''}]` + }) + addAttrs(el, [ + { + name: modelProp, + value: modelExp + } + ]) + } + } + // let wrapper for (const type in eventConfigMap) { let { configs } = eventConfigMap[type] - - let resultName configs.forEach(({ name }) => { if (name) { // 清空原始事件绑定 @@ -1125,21 +1183,15 @@ function processEventReact (el, options, meta) { do { has = getAndRemoveAttr(el, name).has } while (has) - - if (!resultName) { - // 清除修饰符 - resultName = name.replace(/\..*/, '') - } } }) configs = configs.map((item) => { return item.expStr }) - const name = resultName || config[mode].event.getEvent(type) const value = `{{(e)=>this.__invoke(e, [${configs}])}}` addAttrs(el, [ { - name, + name: type, value } ]) @@ -1166,12 +1218,12 @@ function processEventReact (el, options, meta) { // } } - if (wrapper) { - replaceNode(el, wrapper, true) - addChild(wrapper, el) - processAttrs(wrapper, options) - postMoveBaseDirective(wrapper, el) - } + // if (wrapper) { + // replaceNode(el, wrapper, true) + // addChild(wrapper, el) + // processAttrs(wrapper, options) + // postMoveBaseDirective(wrapper, el) + // } } function processEvent (el, options) { @@ -1204,27 +1256,11 @@ function processEvent (el, options) { if (modelExp) { const match = tagRE.exec(modelExp) if (match) { - const modelProp = getAndRemoveAttr(el, config[mode].directive.modelProp).val || config[mode].event.defaultModelProp - const modelEvent = getAndRemoveAttr(el, config[mode].directive.modelEvent).val || config[mode].event.defaultModelEvent - const modelValuePathRaw = getAndRemoveAttr(el, config[mode].directive.modelValuePath).val - const modelValuePath = modelValuePathRaw === undefined ? config[mode].event.defaultModelValuePath : modelValuePathRaw - const modelFilter = getAndRemoveAttr(el, config[mode].directive.modelFilter).val - let modelValuePathArr - try { - modelValuePathArr = JSON5.parse(modelValuePath) - } catch (e) { - if (modelValuePath === '') { - modelValuePathArr = [] - } else { - modelValuePathArr = modelValuePath.split('.') - } - } + const { modelProp, modelEvent, modelFilter, modelValuePathArr, stringifiedModelValue } = getModelConfig(el, match) if (!isValidIdentifierStr(modelEvent)) { warn$1(`EventName ${modelEvent} which is used in ${config[mode].directive.model} must be a valid identifier!`) return } - const modelValue = match[1].trim() - const stringifiedModelValue = stringifyWithResolveComputed(modelValue) // if (forScopes.length) { // stringifiedModelValue = stringifyWithResolveComputed(modelValue) // } else { @@ -2200,7 +2236,7 @@ function processBuiltInComponents (el, meta) { const tag = el.tag if (!meta.builtInComponentsMap[tag]) { if (isReact(mode)) { - meta.builtInComponentsMap[tag] = `${builtInComponentsPrefix}/react/${tag}` + meta.builtInComponentsMap[tag] = `${builtInComponentsPrefix}/react/dist/${tag}` } else { meta.builtInComponentsMap[tag] = `${builtInComponentsPrefix}/${mode}/${tag}` } @@ -2556,7 +2592,7 @@ function processElement (el, root, options, meta) { processFor(el) processRefReact(el, meta) processStyleReact(el) - processEventReact(el, options, meta) + processEventReact(el) processComponentIs(el, options) processSlotReact(el) processAttrs(el, options) diff --git a/packages/webpack-plugin/lib/web/processTemplate.js b/packages/webpack-plugin/lib/web/processTemplate.js index de5fea1485..772ef57c18 100644 --- a/packages/webpack-plugin/lib/web/processTemplate.js +++ b/packages/webpack-plugin/lib/web/processTemplate.js @@ -38,7 +38,7 @@ module.exports = function (template, { const idName = (el && el.match(/#(.*)/) && el.match(/#(.*)/)[1]) || 'app' template = { tag: 'template', - content: `
` + content: `
` } builtInComponentsMap['mpx-keep-alive'] = { resource: addQuery('@mpxjs/webpack-plugin/lib/runtime/components/web/mpx-keep-alive.vue', { isComponent: true }) diff --git a/packages/webpack-plugin/package.json b/packages/webpack-plugin/package.json index c0bae3e302..9670d61192 100644 --- a/packages/webpack-plugin/package.json +++ b/packages/webpack-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@mpxjs/webpack-plugin", - "version": "2.9.55", + "version": "2.9.57", "description": "mpx compile core", "keywords": [ "mpx" @@ -76,12 +76,16 @@ "url": "https://github.com/didi/mpx/issues" }, "scripts": { - "test": "jest" + "test": "jest", + "build": "rimraf ./lib/runtime/components/react/dist && tsc" }, "devDependencies": { + "@ant-design/react-native": "^5.2.2", "@types/babel-traverse": "^6.25.4", "@types/babel-types": "^7.0.4", - "@types/react": "^18.2.79" + "@types/react": "^18.2.79", + "react-native": "^0.74.5", + "rimraf": "^6.0.1" }, "engines": { "node": ">=14.14.0" diff --git a/packages/webpack-plugin/tsconfig.json b/packages/webpack-plugin/tsconfig.json new file mode 100644 index 0000000000..0377bdead9 --- /dev/null +++ b/packages/webpack-plugin/tsconfig.json @@ -0,0 +1,22 @@ +{ + "include": [ + "./lib/runtime/components/react" + ], + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "outDir": "./lib/runtime/components/react/dist", + "noImplicitThis": true, + "noImplicitAny": true, + "skipLibCheck": true, + "strictNullChecks": true, + "allowSyntheticDefaultImports": true, + "moduleResolution": "node", + "jsx": "preserve", + "lib": [ + "esnext", + "dom", + "dom.iterable" + ] + } +} diff --git a/packages/webview-bridge/build/build.js b/packages/webview-bridge/build/build.js index 10dbb07112..f2a5aff4b2 100644 --- a/packages/webview-bridge/build/build.js +++ b/packages/webview-bridge/build/build.js @@ -33,7 +33,7 @@ function buildEntry ({ input, output }) { .then(bundle => bundle.generate(output)) .then(({ output: [{ code }] }) => { if (isProd) { - const minified = (banner ? banner + '\n' : '') + terser.minify(code, { + const minified = terser.minify(code, { toplevel: true, output: { ascii_only: true diff --git a/packages/webview-bridge/dist/webviewbridge.esm.browser.js b/packages/webview-bridge/dist/webviewbridge.esm.browser.js index 7bf61dc52c..903ba156fa 100644 --- a/packages/webview-bridge/dist/webviewbridge.esm.browser.js +++ b/packages/webview-bridge/dist/webviewbridge.esm.browser.js @@ -1,5 +1,5 @@ /** - * mpxjs webview bridge v2.9.44 + * mpxjs webview bridge v2.9.53 * (c) 2024 @mpxjs team * @license Apache */ @@ -90,7 +90,15 @@ if (systemUA.indexOf('AlipayClient') > -1 && systemUA.indexOf('MiniProgram') > - env = 'web'; window.addEventListener('message', (event) => { // 接收web-view的回调 - const { callbackId, error, result } = event.data; + const data = event.data; + let msgData = data; + try { + if (typeof data === 'string') { + msgData = JSON.parse(data); + } + } catch (e) { + } + const { callbackId, error, result } = msgData; if (callbackId !== undefined && callbacks[callbackId]) { if (error) { callbacks[callbackId](error); @@ -167,7 +175,11 @@ function postMessage (type, data = {}) { if (clientUid !== undefined) { postParams.clientUid = clientUid; } - window.parent.postMessage && window.parent.postMessage(postParams, '*'); + if (window.ReactNativeWebView) { + window.ReactNativeWebView.postMessage && window.ReactNativeWebView.postMessage(JSON.stringify(postParams)); + } else { + window.parent.postMessage && window.parent.postMessage(postParams, '*'); + } } else { data({ webapp: true diff --git a/packages/webview-bridge/dist/webviewbridge.esm.browser.min.js b/packages/webview-bridge/dist/webviewbridge.esm.browser.min.js index 4b4efd3be8..f707ba49bf 100644 --- a/packages/webview-bridge/dist/webviewbridge.esm.browser.min.js +++ b/packages/webview-bridge/dist/webviewbridge.esm.browser.min.js @@ -1,11 +1,6 @@ /** - * mpxjs webview bridge v2.9.44 + * mpxjs webview bridge v2.9.53 * (c) 2024 @mpxjs team * @license Apache */ -/** - * mpxjs webview bridge v2.9.44 - * (c) 2024 @mpxjs team - * @license Apache - */ -let e;const o={wx:{url:"https://res.wx.qq.com/open/js/jweixin-1.3.2.js"},qq:{url:"https://qqq.gtimg.cn/miniprogram/webview_jssdk/qqjssdk-1.0.0.js"},my:{url:"https://appx/web-view.min.js"},swan:{url:"https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.4.js"},tt:{url:"https://lf3-cdn-tos.bytegoofy.com/obj/goofy/developer/jssdk/jssdk-1.2.1.js"},...window.sdkUrlMap};let a=null,t=0;const n=function(){const e=location.href,o=/mpx_webview_id=(\d+)/g.exec(e);let a;return o&&o[1]&&(a=+o[1]),a}(),i={},r=navigator.userAgent;r.indexOf("AlipayClient")>-1&&r.indexOf("MiniProgram")>-1?a="my":r.toLowerCase().indexOf("miniprogram")>-1?a=r.indexOf("QQ")>-1?"qq":"wx":r.indexOf("swan/")>-1?a="swan":r.indexOf("toutiao")>-1?a="tt":(a="web",window.addEventListener("message",e=>{const{callbackId:o,error:a,result:t}=e.data;void 0!==o&&i[o]&&(a?i[o](a):i[o](null,t),delete i[o])},!1));let s=!1;function c(o){s?o():e.then(()=>{s=!0,o()})}const d={config(e){"wx"===a?c(()=>{window.wx&&window.wx.config(e)}):console.warn("\u975e\u5fae\u4fe1\u73af\u5883\u4e0d\u9700\u8981\u914d\u7f6econfig")}};function g(e){if("[object Object]"!==Object.prototype.toString.call(e))return e;const o={};for(const a in e)"function"!=typeof e[a]&&(o[a]=e[a]);return o}const w=()=>{const e={wx:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","postMessage","getEnv"]},tt:{keyName:"miniProgram",api:["redirectTo","navigateTo","switchTab","reLaunch","navigateBack","setSwipeBackModeSync","postMessage","getEnv","checkJsApi","chooseImage","compressImage","previewImage","uploadFile","getNetworkType","openLocation","getLocation"]},swan:{keyName:"webView",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]},qq:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]}}[a]||{},o={wx:["checkJSApi","chooseImage","previewImage","uploadImage","downloadImage","getLocalImgData","startRecord","stopRecord","onVoiceRecordEnd","playVoice","pauseVoice","stopVoice","onVoicePlayEnd","uploadVoice","downloadVoice","translateVoice","getNetworkType","openLocation","getLocation","startSearchBeacons","stopSearchBeacons","onSearchBeacons","scanQRCode","chooseCard","addCard","openCard"],my:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","chooseImage","previewImage","getLocation","openLocation","alert","showLoading","hideLoading","getNetworkType","startShare","tradePay","postMessage","onMessage","getEnv"],swan:["makePhoneCall","setClipboardData","getNetworkType","openLocation","getLocation","chooseLocation","chooseImage","previewImage","openShare","navigateToSmartProgram"],web:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage","getLoadError","getLocation"],tt:[]}[a]||[];(e.api||[]).forEach(o=>{d[o]=(...t)=>{c(()=>{window[a][e.keyName][o](...t)})}}),o.forEach(e=>{d[e]=(...o)=>{"web"===a?function(e,o={}){if("getEnv"!==e){const a=++t;i[a]=(e,t)=>{e?(o.fail&&o.fail(e),o.complete&&o.complete(e)):(o.success&&o.success(t),o.complete&&o.complete(t)),delete i[a]};const r={type:e,callbackId:t,payload:g(o)};void 0!==n&&(r.clientUid=n),window.parent.postMessage&&window.parent.postMessage(r,"*")}else o({webapp:!0})}(e,...o):c("wx"===a?()=>{window[a]&&window[a].ready(()=>{window[a][e](...o)})}:()=>{window[a][e](...o)})}})};e="web"!==a?o[a].url?function(e,{time:o=5e3,crossOrigin:a=!1}={}){return Promise.race([new Promise((o,t)=>{const n=document.createElement("script");n.type="text/javascript",n.async="async",a&&(n.crossOrigin="anonymous"),n.onload=n.onreadystatechange=function(){this.readyState&&!/^(loaded|complete)$/.test(this.readyState)||(o(),n.onload=n.onreadystatechange=null)},n.onerror=function(){t(new Error(`load ${e} error`)),n.onerror=null},n.src=e,document.getElementsByTagName("head")[0].appendChild(n)}),new Promise((a,t)=>{setTimeout(()=>{t(new Error(`load ${e} timeout`))},o)})])}(o[a].url):Promise.reject(new Error("\u672a\u627e\u5230\u5bf9\u5e94\u7684sdk")):Promise.resolve(),w();export default d; \ No newline at end of file +let e;const o={wx:{url:"https://res.wx.qq.com/open/js/jweixin-1.3.2.js"},qq:{url:"https://qqq.gtimg.cn/miniprogram/webview_jssdk/qqjssdk-1.0.0.js"},my:{url:"https://appx/web-view.min.js"},swan:{url:"https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.4.js"},tt:{url:"https://lf3-cdn-tos.bytegoofy.com/obj/goofy/developer/jssdk/jssdk-1.2.1.js"},...window.sdkUrlMap};let t=null,a=0;const n=function(){const e=location.href,o=/mpx_webview_id=(\d+)/g.exec(e);let t;return o&&o[1]&&(t=+o[1]),t}(),i={},s=navigator.userAgent;s.indexOf("AlipayClient")>-1&&s.indexOf("MiniProgram")>-1?t="my":s.toLowerCase().indexOf("miniprogram")>-1?t=s.indexOf("QQ")>-1?"qq":"wx":s.indexOf("swan/")>-1?t="swan":s.indexOf("toutiao")>-1?t="tt":(t="web",window.addEventListener("message",e=>{const o=e.data;let t=o;try{"string"==typeof o&&(t=JSON.parse(o))}catch(e){}const{callbackId:a,error:n,result:s}=t;void 0!==a&&i[a]&&(n?i[a](n):i[a](null,s),delete i[a])},!1));let r=!1;function c(o){r?o():e.then(()=>{r=!0,o()})}const d={config(e){"wx"===t?c(()=>{window.wx&&window.wx.config(e)}):console.warn("\u975e\u5fae\u4fe1\u73af\u5883\u4e0d\u9700\u8981\u914d\u7f6econfig")}};function w(e){if("[object Object]"!==Object.prototype.toString.call(e))return e;const o={};for(const t in e)"function"!=typeof e[t]&&(o[t]=e[t]);return o}const g=()=>{const e={wx:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","postMessage","getEnv"]},tt:{keyName:"miniProgram",api:["redirectTo","navigateTo","switchTab","reLaunch","navigateBack","setSwipeBackModeSync","postMessage","getEnv","checkJsApi","chooseImage","compressImage","previewImage","uploadFile","getNetworkType","openLocation","getLocation"]},swan:{keyName:"webView",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]},qq:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]}}[t]||{},o={wx:["checkJSApi","chooseImage","previewImage","uploadImage","downloadImage","getLocalImgData","startRecord","stopRecord","onVoiceRecordEnd","playVoice","pauseVoice","stopVoice","onVoicePlayEnd","uploadVoice","downloadVoice","translateVoice","getNetworkType","openLocation","getLocation","startSearchBeacons","stopSearchBeacons","onSearchBeacons","scanQRCode","chooseCard","addCard","openCard"],my:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","chooseImage","previewImage","getLocation","openLocation","alert","showLoading","hideLoading","getNetworkType","startShare","tradePay","postMessage","onMessage","getEnv"],swan:["makePhoneCall","setClipboardData","getNetworkType","openLocation","getLocation","chooseLocation","chooseImage","previewImage","openShare","navigateToSmartProgram"],web:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage","getLoadError","getLocation"],tt:[]}[t]||[];(e.api||[]).forEach(o=>{d[o]=(...a)=>{c(()=>{window[t][e.keyName][o](...a)})}}),o.forEach(e=>{d[e]=(...o)=>{"web"===t?function(e,o={}){if("getEnv"!==e){const t=++a;i[t]=(e,a)=>{e?(o.fail&&o.fail(e),o.complete&&o.complete(e)):(o.success&&o.success(a),o.complete&&o.complete(a)),delete i[t]};const s={type:e,callbackId:a,payload:w(o)};void 0!==n&&(s.clientUid=n),window.ReactNativeWebView?window.ReactNativeWebView.postMessage&&window.ReactNativeWebView.postMessage(JSON.stringify(s)):window.parent.postMessage&&window.parent.postMessage(s,"*")}else o({webapp:!0})}(e,...o):c("wx"===t?()=>{window[t]&&window[t].ready(()=>{window[t][e](...o)})}:()=>{window[t][e](...o)})}})};e="web"!==t?o[t].url?function(e,{time:o=5e3,crossOrigin:t=!1}={}){return Promise.race([new Promise((o,a)=>{const n=document.createElement("script");n.type="text/javascript",n.async="async",t&&(n.crossOrigin="anonymous"),n.onload=n.onreadystatechange=function(){this.readyState&&!/^(loaded|complete)$/.test(this.readyState)||(o(),n.onload=n.onreadystatechange=null)},n.onerror=function(){a(new Error(`load ${e} error`)),n.onerror=null},n.src=e,document.getElementsByTagName("head")[0].appendChild(n)}),new Promise((t,a)=>{setTimeout(()=>{a(new Error(`load ${e} timeout`))},o)})])}(o[t].url):Promise.reject(new Error("\u672a\u627e\u5230\u5bf9\u5e94\u7684sdk")):Promise.resolve(),g();export default d; \ No newline at end of file diff --git a/packages/webview-bridge/dist/webviewbridge.esm.js b/packages/webview-bridge/dist/webviewbridge.esm.js index 1fd64b0397..c45b54c0b5 100644 --- a/packages/webview-bridge/dist/webviewbridge.esm.js +++ b/packages/webview-bridge/dist/webviewbridge.esm.js @@ -1,5 +1,5 @@ /** - * mpxjs webview bridge v2.9.44 + * mpxjs webview bridge v2.9.53 * (c) 2024 @mpxjs team * @license Apache */ @@ -133,10 +133,17 @@ if (systemUA.indexOf('AlipayClient') > -1 && systemUA.indexOf('MiniProgram') > - env = 'web'; window.addEventListener('message', function (event) { // 接收web-view的回调 - var _event$data = event.data, - callbackId = _event$data.callbackId, - error = _event$data.error, - result = _event$data.result; + var data = event.data; + var msgData = data; + try { + if (typeof data === 'string') { + msgData = JSON.parse(data); + } + } catch (e) {} + var _msgData = msgData, + callbackId = _msgData.callbackId, + error = _msgData.error, + result = _msgData.result; if (callbackId !== undefined && callbacks[callbackId]) { if (error) { callbacks[callbackId](error); @@ -209,7 +216,11 @@ function postMessage(type) { if (clientUid !== undefined) { postParams.clientUid = clientUid; } - window.parent.postMessage && window.parent.postMessage(postParams, '*'); + if (window.ReactNativeWebView) { + window.ReactNativeWebView.postMessage && window.ReactNativeWebView.postMessage(JSON.stringify(postParams)); + } else { + window.parent.postMessage && window.parent.postMessage(postParams, '*'); + } } else { data({ webapp: true diff --git a/packages/webview-bridge/dist/webviewbridge.js b/packages/webview-bridge/dist/webviewbridge.js index af3c29947d..13c40824a5 100644 --- a/packages/webview-bridge/dist/webviewbridge.js +++ b/packages/webview-bridge/dist/webviewbridge.js @@ -1,5 +1,5 @@ /** - * mpxjs webview bridge v2.9.44 + * mpxjs webview bridge v2.9.53 * (c) 2024 @mpxjs team * @license Apache */ @@ -139,10 +139,17 @@ env = 'web'; window.addEventListener('message', function (event) { // 接收web-view的回调 - var _event$data = event.data, - callbackId = _event$data.callbackId, - error = _event$data.error, - result = _event$data.result; + var data = event.data; + var msgData = data; + try { + if (typeof data === 'string') { + msgData = JSON.parse(data); + } + } catch (e) {} + var _msgData = msgData, + callbackId = _msgData.callbackId, + error = _msgData.error, + result = _msgData.result; if (callbackId !== undefined && callbacks[callbackId]) { if (error) { callbacks[callbackId](error); @@ -215,7 +222,11 @@ if (clientUid !== undefined) { postParams.clientUid = clientUid; } - window.parent.postMessage && window.parent.postMessage(postParams, '*'); + if (window.ReactNativeWebView) { + window.ReactNativeWebView.postMessage && window.ReactNativeWebView.postMessage(JSON.stringify(postParams)); + } else { + window.parent.postMessage && window.parent.postMessage(postParams, '*'); + } } else { data({ webapp: true diff --git a/packages/webview-bridge/dist/webviewbridge.min.js b/packages/webview-bridge/dist/webviewbridge.min.js index d31f3b9b96..b94c23c965 100644 --- a/packages/webview-bridge/dist/webviewbridge.min.js +++ b/packages/webview-bridge/dist/webviewbridge.min.js @@ -1,11 +1,6 @@ /** - * mpxjs webview bridge v2.9.44 + * mpxjs webview bridge v2.9.53 * (c) 2024 @mpxjs team * @license Apache */ -/** - * mpxjs webview bridge v2.9.44 - * (c) 2024 @mpxjs team - * @license Apache - */ -var e,t;e=this,t=function(){"use strict";function e(e,t,o){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var o=e[Symbol.toPrimitive];if(void 0!==o){var n=o.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function t(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}var o,n,a,r,i=function(o){for(var n=1;n-1&&u.indexOf("MiniProgram")>-1?c="my":u.toLowerCase().indexOf("miniprogram")>-1?c=u.indexOf("QQ")>-1?"qq":"wx":u.indexOf("swan/")>-1?c="swan":u.indexOf("toutiao")>-1?c="tt":(c="web",window.addEventListener("message",(function(e){var t=e.data,o=t.callbackId,n=t.error,a=t.result;void 0!==o&&d[o]&&(n?d[o](n):d[o](null,a),delete d[o])}),!1));var g=!1;function l(e){g?e():o.then((function(){g=!0,e()}))}var w={config:function(e){"wx"===c?l((function(){window.wx&&window.wx.config(e)})):console.warn("\u975e\u5fae\u4fe1\u73af\u5883\u4e0d\u9700\u8981\u914d\u7f6econfig")}};function f(e){if("[object Object]"!==Object.prototype.toString.call(e))return e;var t={};for(var o in e)"function"!=typeof e[o]&&(t[o]=e[o]);return t}function m(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("getEnv"!==e){var o=++s;d[o]=function(e,n){e?(t.fail&&t.fail(e),t.complete&&t.complete(e)):(t.success&&t.success(n),t.complete&&t.complete(n)),delete d[o]};var n={type:e,callbackId:s,payload:f(t)};void 0!==p&&(n.clientUid=p),window.parent.postMessage&&window.parent.postMessage(n,"*")}else t({webapp:!0})}var v=function(){var e={wx:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","postMessage","getEnv"]},tt:{keyName:"miniProgram",api:["redirectTo","navigateTo","switchTab","reLaunch","navigateBack","setSwipeBackModeSync","postMessage","getEnv","checkJsApi","chooseImage","compressImage","previewImage","uploadFile","getNetworkType","openLocation","getLocation"]},swan:{keyName:"webView",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]},qq:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]}}[c]||{},t={wx:["checkJSApi","chooseImage","previewImage","uploadImage","downloadImage","getLocalImgData","startRecord","stopRecord","onVoiceRecordEnd","playVoice","pauseVoice","stopVoice","onVoicePlayEnd","uploadVoice","downloadVoice","translateVoice","getNetworkType","openLocation","getLocation","startSearchBeacons","stopSearchBeacons","onSearchBeacons","scanQRCode","chooseCard","addCard","openCard"],my:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","chooseImage","previewImage","getLocation","openLocation","alert","showLoading","hideLoading","getNetworkType","startShare","tradePay","postMessage","onMessage","getEnv"],swan:["makePhoneCall","setClipboardData","getNetworkType","openLocation","getLocation","chooseLocation","chooseImage","previewImage","openShare","navigateToSmartProgram"],web:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage","getLoadError","getLocation"],tt:[]}[c]||[];(e.api||[]).forEach((function(t){w[t]=function(){for(var o=arguments.length,n=new Array(o),a=0;a1&&void 0!==arguments[1]?arguments[1]:{},o=t.time,n=void 0===o?5e3:o,a=t.crossOrigin,r=void 0!==a&&a;function i(){return new Promise((function(t,o){var n=document.createElement("script");n.type="text/javascript",n.async="async",r&&(n.crossOrigin="anonymous"),n.onload=n.onreadystatechange=function(){this.readyState&&!/^(loaded|complete)$/.test(this.readyState)||(t(),n.onload=n.onreadystatechange=null)},n.onerror=function(){o(new Error("load ".concat(e," error"))),n.onerror=null},n.src=e,document.getElementsByTagName("head")[0].appendChild(n)}))}function c(){return new Promise((function(t,o){setTimeout((function(){o(new Error("load ".concat(e," timeout")))}),n)}))}return Promise.race([i(),c()])}(i[c].url):Promise.reject(new Error("\u672a\u627e\u5230\u5bf9\u5e94\u7684sdk")):Promise.resolve(),v(),w},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).mpx=t(); \ No newline at end of file +var e,t;e=this,t=function(){"use strict";function e(e,t,o){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var o=e[Symbol.toPrimitive];if(void 0!==o){var n=o.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function t(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}var o,n,a,r,i=function(o){for(var n=1;n-1&&g.indexOf("MiniProgram")>-1?c="my":g.toLowerCase().indexOf("miniprogram")>-1?c=g.indexOf("QQ")>-1?"qq":"wx":g.indexOf("swan/")>-1?c="swan":g.indexOf("toutiao")>-1?c="tt":(c="web",window.addEventListener("message",(function(e){var t=e.data,o=t;try{"string"==typeof t&&(o=JSON.parse(t))}catch(e){}var n=o,a=n.callbackId,r=n.error,i=n.result;void 0!==a&&d[a]&&(r?d[a](r):d[a](null,i),delete d[a])}),!1));var u=!1;function w(e){u?e():o.then((function(){u=!0,e()}))}var l={config:function(e){"wx"===c?w((function(){window.wx&&window.wx.config(e)})):console.warn("\u975e\u5fae\u4fe1\u73af\u5883\u4e0d\u9700\u8981\u914d\u7f6econfig")}};function f(e){if("[object Object]"!==Object.prototype.toString.call(e))return e;var t={};for(var o in e)"function"!=typeof e[o]&&(t[o]=e[o]);return t}function m(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("getEnv"!==e){var o=++s;d[o]=function(e,n){e?(t.fail&&t.fail(e),t.complete&&t.complete(e)):(t.success&&t.success(n),t.complete&&t.complete(n)),delete d[o]};var n={type:e,callbackId:s,payload:f(t)};void 0!==p&&(n.clientUid=p),window.ReactNativeWebView?window.ReactNativeWebView.postMessage&&window.ReactNativeWebView.postMessage(JSON.stringify(n)):window.parent.postMessage&&window.parent.postMessage(n,"*")}else t({webapp:!0})}var v=function(){var e={wx:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","postMessage","getEnv"]},tt:{keyName:"miniProgram",api:["redirectTo","navigateTo","switchTab","reLaunch","navigateBack","setSwipeBackModeSync","postMessage","getEnv","checkJsApi","chooseImage","compressImage","previewImage","uploadFile","getNetworkType","openLocation","getLocation"]},swan:{keyName:"webView",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]},qq:{keyName:"miniProgram",api:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage"]}}[c]||{},t={wx:["checkJSApi","chooseImage","previewImage","uploadImage","downloadImage","getLocalImgData","startRecord","stopRecord","onVoiceRecordEnd","playVoice","pauseVoice","stopVoice","onVoicePlayEnd","uploadVoice","downloadVoice","translateVoice","getNetworkType","openLocation","getLocation","startSearchBeacons","stopSearchBeacons","onSearchBeacons","scanQRCode","chooseCard","addCard","openCard"],my:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","chooseImage","previewImage","getLocation","openLocation","alert","showLoading","hideLoading","getNetworkType","startShare","tradePay","postMessage","onMessage","getEnv"],swan:["makePhoneCall","setClipboardData","getNetworkType","openLocation","getLocation","chooseLocation","chooseImage","previewImage","openShare","navigateToSmartProgram"],web:["navigateTo","navigateBack","switchTab","reLaunch","redirectTo","getEnv","postMessage","getLoadError","getLocation"],tt:[]}[c]||[];(e.api||[]).forEach((function(t){l[t]=function(){for(var o=arguments.length,n=new Array(o),a=0;a1&&void 0!==arguments[1]?arguments[1]:{},o=t.time,n=void 0===o?5e3:o,a=t.crossOrigin,r=void 0!==a&&a;function i(){return new Promise((function(t,o){var n=document.createElement("script");n.type="text/javascript",n.async="async",r&&(n.crossOrigin="anonymous"),n.onload=n.onreadystatechange=function(){this.readyState&&!/^(loaded|complete)$/.test(this.readyState)||(t(),n.onload=n.onreadystatechange=null)},n.onerror=function(){o(new Error("load ".concat(e," error"))),n.onerror=null},n.src=e,document.getElementsByTagName("head")[0].appendChild(n)}))}function c(){return new Promise((function(t,o){setTimeout((function(){o(new Error("load ".concat(e," timeout")))}),n)}))}return Promise.race([i(),c()])}(i[c].url):Promise.reject(new Error("\u672a\u627e\u5230\u5bf9\u5e94\u7684sdk")):Promise.resolve(),v(),l},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).mpx=t(); \ No newline at end of file diff --git a/packages/webview-bridge/src/index.js b/packages/webview-bridge/src/index.js index 7e58692a95..a3b9fd6ce6 100644 --- a/packages/webview-bridge/src/index.js +++ b/packages/webview-bridge/src/index.js @@ -46,7 +46,15 @@ if (systemUA.indexOf('AlipayClient') > -1 && systemUA.indexOf('MiniProgram') > - env = 'web' window.addEventListener('message', (event) => { // 接收web-view的回调 - const { callbackId, error, result } = event.data + const data = event.data + let msgData = data + try { + if (typeof data === 'string') { + msgData = JSON.parse(data) + } + } catch (e) { + } + const { callbackId, error, result } = msgData if (callbackId !== undefined && callbacks[callbackId]) { if (error) { callbacks[callbackId](error) @@ -123,7 +131,11 @@ function postMessage (type, data = {}) { if (clientUid !== undefined) { postParams.clientUid = clientUid } - window.parent.postMessage && window.parent.postMessage(postParams, '*') + if (window.ReactNativeWebView) { + window.ReactNativeWebView.postMessage && window.ReactNativeWebView.postMessage(JSON.stringify(postParams)) + } else { + window.parent.postMessage && window.parent.postMessage(postParams, '*') + } } else { data({ webapp: true