@mpxjs/core 2.10.16 → 2.10.17-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/global.d.ts +4 -1
- package/@types/index.d.ts +24 -28
- package/package.json +9 -5
- package/src/convertor/convertor.js +3 -1
- package/src/convertor/getConvertMode.js +2 -1
- package/src/convertor/wxToAli.js +1 -1
- package/src/convertor/wxToKs.js +21 -0
- package/src/convertor/wxToReact.js +1 -1
- package/src/convertor/wxToSwan.js +1 -1
- package/src/convertor/wxToTt.js +1 -1
- package/src/convertor/wxToWeb.js +9 -2
- package/src/core/proxy.js +14 -2
- package/src/core/transferOptions.js +1 -1
- package/src/helper/MpxScroll/index.js +17 -5
- package/src/platform/builtInMixins/index.js +7 -3
- package/src/platform/builtInMixins/pageStatusMixin.js +14 -2
- package/src/platform/builtInMixins/refsMixin.js +47 -46
- package/src/platform/builtInMixins/renderHelperMixin.js +40 -38
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +106 -29
- package/src/platform/createApp.ios.js +10 -24
- package/src/platform/env/navigationHelper.ios.js +3 -2
- package/src/platform/patch/getDefaultOptions.ios.js +65 -27
- package/LICENSE +0 -433
- package/src/platform/env/nav.js +0 -137
- package/src/platform/patch/react/getDefaultOptions.ios.js +0 -0
|
@@ -1,37 +1,74 @@
|
|
|
1
|
-
import { isObject, isArray, dash2hump, cached, isEmptyObject, hasOwn } from '@mpxjs/utils'
|
|
2
|
-
import {
|
|
1
|
+
import { isObject, isArray, dash2hump, cached, isEmptyObject, hasOwn, getFocusedNavigation } from '@mpxjs/utils'
|
|
2
|
+
import { StyleSheet, Dimensions } from 'react-native'
|
|
3
|
+
import { reactive } from '../../observer/reactive'
|
|
3
4
|
import Mpx from '../../index'
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
global.__mpxAppDimensionsInfo = {
|
|
7
|
+
window: Dimensions.get('window'),
|
|
8
|
+
screen: Dimensions.get('screen')
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
+
global.__mpxSizeCount = 0
|
|
11
|
+
global.__mpxPageSizeCountMap = reactive({})
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
global.__GCC = function (className, classMap, classMapValueCache) {
|
|
14
|
+
if (!classMapValueCache.has(className)) {
|
|
15
|
+
const styleObj = classMap[className]?.(global.__formatValue)
|
|
16
|
+
styleObj && classMapValueCache.set(className, styleObj)
|
|
17
|
+
}
|
|
18
|
+
return classMapValueCache.get(className)
|
|
19
|
+
}
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
let dimensionsInfoInitialized = false
|
|
22
|
+
function useDimensionsInfo (dimensions) {
|
|
23
|
+
dimensionsInfoInitialized = true
|
|
16
24
|
if (typeof Mpx.config.rnConfig?.customDimensions === 'function') {
|
|
17
25
|
dimensions = Mpx.config.rnConfig.customDimensions(dimensions) || dimensions
|
|
18
26
|
}
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
global.__mpxAppDimensionsInfo.window = dimensions.window
|
|
28
|
+
global.__mpxAppDimensionsInfo.screen = dimensions.screen
|
|
21
29
|
}
|
|
22
30
|
|
|
23
|
-
|
|
31
|
+
function getPageSize (window = global.__mpxAppDimensionsInfo.screen) {
|
|
32
|
+
return window.width + 'x' + window.height
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
Dimensions.addEventListener('change', ({ window, screen }) => {
|
|
36
|
+
const oldScreen = getPageSize(global.__mpxAppDimensionsInfo.screen)
|
|
37
|
+
useDimensionsInfo({ window, screen })
|
|
38
|
+
|
|
39
|
+
// 对比 screen 高宽是否存在变化
|
|
40
|
+
if (getPageSize(screen) === oldScreen) return
|
|
41
|
+
|
|
42
|
+
global.__classCaches?.forEach(cache => cache?.clear())
|
|
43
|
+
|
|
44
|
+
// 更新全局和栈顶页面的标记,其他后台页面的标记在show之后更新
|
|
45
|
+
global.__mpxSizeCount++
|
|
46
|
+
|
|
47
|
+
const navigation = getFocusedNavigation()
|
|
48
|
+
|
|
49
|
+
if (navigation) {
|
|
50
|
+
global.__mpxPageSizeCountMap[navigation.pageId] = global.__mpxSizeCount
|
|
51
|
+
if (hasOwn(global.__mpxPageStatusMap, navigation.pageId)) {
|
|
52
|
+
global.__mpxPageStatusMap[navigation.pageId] = `resize${global.__mpxSizeCount}`
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
})
|
|
24
56
|
|
|
57
|
+
// TODO: 1 目前测试鸿蒙下折叠屏screen固定为展开状态下屏幕尺寸,仅window会变化,且window包含状态栏高度
|
|
58
|
+
// TODO: 2 存在部分安卓折叠屏机型在折叠/展开切换时,Dimensions监听到的width/height尺寸错误,并触发多次问题
|
|
25
59
|
function rpx (value) {
|
|
60
|
+
const screenInfo = global.__mpxAppDimensionsInfo.screen
|
|
26
61
|
// rn 单位 dp = 1(css)px = 1 物理像素 * pixelRatio(像素比)
|
|
27
62
|
// px = rpx * (750 / 屏幕宽度)
|
|
28
|
-
return value * width / 750
|
|
63
|
+
return value * screenInfo.width / 750
|
|
29
64
|
}
|
|
30
65
|
function vw (value) {
|
|
31
|
-
|
|
66
|
+
const screenInfo = global.__mpxAppDimensionsInfo.screen
|
|
67
|
+
return value * screenInfo.width / 100
|
|
32
68
|
}
|
|
33
69
|
function vh (value) {
|
|
34
|
-
|
|
70
|
+
const screenInfo = global.__mpxAppDimensionsInfo.screen
|
|
71
|
+
return value * screenInfo.height / 100
|
|
35
72
|
}
|
|
36
73
|
|
|
37
74
|
const unit = {
|
|
@@ -42,8 +79,14 @@ const unit = {
|
|
|
42
79
|
|
|
43
80
|
const empty = {}
|
|
44
81
|
|
|
45
|
-
function formatValue (value) {
|
|
46
|
-
if (
|
|
82
|
+
function formatValue (value, unitType) {
|
|
83
|
+
if (!dimensionsInfoInitialized) useDimensionsInfo(global.__mpxAppDimensionsInfo)
|
|
84
|
+
if (unitType === 'hairlineWidth') {
|
|
85
|
+
return StyleSheet.hairlineWidth
|
|
86
|
+
}
|
|
87
|
+
if (unitType && typeof unit[unitType] === 'function') {
|
|
88
|
+
return unit[unitType](+value)
|
|
89
|
+
}
|
|
47
90
|
const matched = unitRegExp.exec(value)
|
|
48
91
|
if (matched) {
|
|
49
92
|
if (!matched[2] || matched[2] === 'px') {
|
|
@@ -184,29 +227,57 @@ function isNativeStyle (style) {
|
|
|
184
227
|
)
|
|
185
228
|
}
|
|
186
229
|
|
|
230
|
+
function getMediaStyle (media) {
|
|
231
|
+
if (!media || !media.length) return {}
|
|
232
|
+
const { width } = global.__mpxAppDimensionsInfo.screen
|
|
233
|
+
return media.reduce((styleObj, item) => {
|
|
234
|
+
const { options = {}, value = {} } = item
|
|
235
|
+
const { minWidth, maxWidth } = options
|
|
236
|
+
if (!isNaN(minWidth) && !isNaN(maxWidth) && width >= minWidth && width <= maxWidth) {
|
|
237
|
+
Object.assign(styleObj, value)
|
|
238
|
+
} else if (!isNaN(minWidth) && width >= minWidth) {
|
|
239
|
+
Object.assign(styleObj, value)
|
|
240
|
+
} else if (!isNaN(maxWidth) && width <= maxWidth) {
|
|
241
|
+
Object.assign(styleObj, value)
|
|
242
|
+
}
|
|
243
|
+
return styleObj
|
|
244
|
+
}, {})
|
|
245
|
+
}
|
|
246
|
+
|
|
187
247
|
export default function styleHelperMixin () {
|
|
188
248
|
return {
|
|
189
249
|
methods: {
|
|
250
|
+
__getSizeCount () {
|
|
251
|
+
return global.__mpxPageSizeCountMap[this.__pageId]
|
|
252
|
+
},
|
|
190
253
|
__getClass (staticClass, dynamicClass) {
|
|
191
254
|
return concat(staticClass, stringifyDynamicClass(dynamicClass))
|
|
192
255
|
},
|
|
193
256
|
__getStyle (staticClass, dynamicClass, staticStyle, dynamicStyle, hide) {
|
|
194
257
|
const isNativeStaticStyle = staticStyle && isNativeStyle(staticStyle)
|
|
195
258
|
let result = isNativeStaticStyle ? [] : {}
|
|
196
|
-
const mergeResult = isNativeStaticStyle ? (
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const appClassMap = global.__getAppClassMap?.() || {}
|
|
259
|
+
const mergeResult = isNativeStaticStyle ? (...args) => result.push(...args) : (...args) => Object.assign(result, ...args)
|
|
260
|
+
// 使用一下 __getSizeCount 触发其 get
|
|
261
|
+
this.__getSizeCount()
|
|
200
262
|
|
|
201
263
|
if (staticClass || dynamicClass) {
|
|
202
264
|
// todo 当前为了复用小程序unocss产物,暂时进行mpEscape,等后续正式支持unocss后可不进行mpEscape
|
|
203
265
|
const classString = mpEscape(concat(staticClass, stringifyDynamicClass(dynamicClass)))
|
|
266
|
+
|
|
204
267
|
classString.split(/\s+/).forEach((className) => {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
268
|
+
let localStyle, appStyle
|
|
269
|
+
if (localStyle = this.__getClassStyle?.(className)) {
|
|
270
|
+
if (localStyle._media?.length) {
|
|
271
|
+
mergeResult(localStyle._default, getMediaStyle(localStyle._media))
|
|
272
|
+
} else {
|
|
273
|
+
mergeResult(localStyle)
|
|
274
|
+
}
|
|
275
|
+
} else if (appStyle = global.__getAppClassStyle?.(className)) {
|
|
276
|
+
if (appStyle._media?.length) {
|
|
277
|
+
mergeResult(appStyle._default, getMediaStyle(appStyle._media))
|
|
278
|
+
} else {
|
|
279
|
+
mergeResult(appStyle)
|
|
280
|
+
}
|
|
210
281
|
} else if (isObject(this.__props[className])) {
|
|
211
282
|
// externalClasses必定以对象形式传递下来
|
|
212
283
|
mergeResult(this.__props[className])
|
|
@@ -236,8 +307,14 @@ export default function styleHelperMixin () {
|
|
|
236
307
|
flex: 0,
|
|
237
308
|
height: 0,
|
|
238
309
|
width: 0,
|
|
239
|
-
|
|
240
|
-
|
|
310
|
+
paddingTop: 0,
|
|
311
|
+
paddingRight: 0,
|
|
312
|
+
paddingBottom: 0,
|
|
313
|
+
paddingLeft: 0,
|
|
314
|
+
marginTop: 0,
|
|
315
|
+
marginRight: 0,
|
|
316
|
+
marginBottom: 0,
|
|
317
|
+
marginLeft: 0,
|
|
241
318
|
overflow: 'hidden'
|
|
242
319
|
})
|
|
243
320
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import transferOptions from '../core/transferOptions'
|
|
2
2
|
import builtInKeysMap from './patch/builtInKeysMap'
|
|
3
|
-
import { makeMap, spreadProp, getFocusedNavigation, hasOwn } from '@mpxjs/utils'
|
|
3
|
+
import { makeMap, spreadProp, getFocusedNavigation, hasOwn, callWithErrorHandling } from '@mpxjs/utils'
|
|
4
4
|
import { mergeLifecycle } from '../convertor/mergeLifecycle'
|
|
5
5
|
import { LIFECYCLE } from '../platform/patch/lifecycle/index'
|
|
6
6
|
import Mpx from '../index'
|
|
@@ -10,14 +10,10 @@ import { createElement, memo, useRef, useEffect } from 'react'
|
|
|
10
10
|
import * as ReactNative from 'react-native'
|
|
11
11
|
import { initAppProvides } from './export/inject'
|
|
12
12
|
import { NavigationContainer, createNativeStackNavigator, SafeAreaProvider, GestureHandlerRootView } from './env/navigationHelper'
|
|
13
|
-
import
|
|
13
|
+
import MpxNav from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-nav'
|
|
14
14
|
|
|
15
15
|
const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app)
|
|
16
16
|
|
|
17
|
-
function getPageSize (window = ReactNative.Dimensions.get('window')) {
|
|
18
|
-
return window.width + 'x' + window.height
|
|
19
|
-
}
|
|
20
|
-
|
|
21
17
|
function filterOptions (options, appData) {
|
|
22
18
|
const newOptions = {}
|
|
23
19
|
Object.keys(options).forEach(key => {
|
|
@@ -66,21 +62,20 @@ export default function createApp (options) {
|
|
|
66
62
|
flex: 1
|
|
67
63
|
}
|
|
68
64
|
},
|
|
69
|
-
createElement(
|
|
70
|
-
pageConfig
|
|
65
|
+
createElement(MpxNav, {
|
|
66
|
+
pageConfig,
|
|
71
67
|
navigation
|
|
72
68
|
}),
|
|
73
69
|
children
|
|
74
70
|
)
|
|
75
71
|
}
|
|
76
72
|
const getComponent = () => {
|
|
77
|
-
return item.displayName ? item : item
|
|
73
|
+
return item.displayName ? item : callWithErrorHandling(item, null, 'require page script')
|
|
78
74
|
}
|
|
79
75
|
if (key === initialRouteName) {
|
|
80
76
|
return createElement(Stack.Screen, {
|
|
81
77
|
name: key,
|
|
82
78
|
getComponent,
|
|
83
|
-
initialParams,
|
|
84
79
|
layout: headerLayout
|
|
85
80
|
})
|
|
86
81
|
}
|
|
@@ -208,29 +203,20 @@ export default function createApp (options) {
|
|
|
208
203
|
if (Mpx.config.rnConfig.disableAppStateListener) return
|
|
209
204
|
onAppStateChange(state)
|
|
210
205
|
})
|
|
211
|
-
|
|
212
|
-
let count = 0
|
|
213
|
-
let lastPageSize = getPageSize()
|
|
214
|
-
const resizeSubScription = ReactNative.Dimensions.addEventListener('change', ({ window }) => {
|
|
215
|
-
const pageSize = getPageSize(window)
|
|
216
|
-
if (pageSize === lastPageSize) return
|
|
217
|
-
lastPageSize = pageSize
|
|
218
|
-
const navigation = getFocusedNavigation()
|
|
219
|
-
if (navigation && hasOwn(global.__mpxPageStatusMap, navigation.pageId)) {
|
|
220
|
-
global.__mpxPageStatusMap[navigation.pageId] = `resize${count++}`
|
|
221
|
-
}
|
|
222
|
-
})
|
|
223
206
|
return () => {
|
|
224
207
|
appState.state = 'exit'
|
|
225
208
|
changeSubscription && changeSubscription.remove()
|
|
226
|
-
resizeSubScription && resizeSubScription.remove()
|
|
227
209
|
}
|
|
228
210
|
}, [])
|
|
229
211
|
|
|
230
212
|
const { initialRouteName, initialParams } = initialRouteRef.current
|
|
213
|
+
if (!global.__mpxAppHotLaunched) {
|
|
214
|
+
global.__mpxInitialRouteName = initialRouteName
|
|
215
|
+
global.__mpxInitialRunParams = initialParams
|
|
216
|
+
}
|
|
231
217
|
const navScreenOpts = {
|
|
232
218
|
headerShown: false,
|
|
233
|
-
statusBarTranslucent: true,
|
|
219
|
+
statusBarTranslucent: Mpx.config.rnConfig.statusBarTranslucent ?? true,
|
|
234
220
|
statusBarBackgroundColor: 'transparent'
|
|
235
221
|
}
|
|
236
222
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
|
2
2
|
import { NavigationContainer, StackActions } from '@react-navigation/native'
|
|
3
3
|
import PortalHost from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-portal/portal-host'
|
|
4
|
-
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
4
|
+
import { SafeAreaProvider, useSafeAreaInsets, initialWindowMetrics } from 'react-native-safe-area-context'
|
|
5
5
|
import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
|
6
6
|
|
|
7
7
|
export {
|
|
@@ -11,5 +11,6 @@ export {
|
|
|
11
11
|
GestureHandlerRootView,
|
|
12
12
|
PortalHost,
|
|
13
13
|
SafeAreaProvider,
|
|
14
|
-
useSafeAreaInsets
|
|
14
|
+
useSafeAreaInsets,
|
|
15
|
+
initialWindowMetrics
|
|
15
16
|
}
|
|
@@ -3,25 +3,24 @@ import * as ReactNative from 'react-native'
|
|
|
3
3
|
import { ReactiveEffect } from '../../observer/effect'
|
|
4
4
|
import { watch } from '../../observer/watch'
|
|
5
5
|
import { del, reactive, set } from '../../observer/reactive'
|
|
6
|
-
import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, dash2hump, callWithErrorHandling, wrapMethodsWithErrorHandling, error, setFocusedNavigation } from '@mpxjs/utils'
|
|
6
|
+
import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, dash2hump, callWithErrorHandling, wrapMethodsWithErrorHandling, error, setFocusedNavigation, getDefaultValueByType } from '@mpxjs/utils'
|
|
7
7
|
import MpxProxy from '../../core/proxy'
|
|
8
8
|
import { BEFOREUPDATE, ONLOAD, UPDATED, ONSHOW, ONHIDE, ONRESIZE, REACTHOOKSEXEC } from '../../core/innerLifecycle'
|
|
9
9
|
import mergeOptions from '../../core/mergeOptions'
|
|
10
10
|
import { queueJob, hasPendingJob } from '../../observer/scheduler'
|
|
11
11
|
import { createSelectorQuery, createIntersectionObserver } from '@mpxjs/api-proxy'
|
|
12
|
-
import MpxKeyboardAvoidingView from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view'
|
|
13
12
|
import {
|
|
14
13
|
IntersectionObserverContext,
|
|
15
14
|
KeyboardAvoidContext,
|
|
15
|
+
ProviderContext,
|
|
16
16
|
RouteContext
|
|
17
17
|
} from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/context'
|
|
18
|
-
import { PortalHost, useSafeAreaInsets } from '../env/navigationHelper'
|
|
19
|
-
import { useInnerHeaderHeight } from '
|
|
18
|
+
import { PortalHost, useSafeAreaInsets, initialWindowMetrics } from '../env/navigationHelper'
|
|
19
|
+
import { useInnerHeaderHeight } from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-nav'
|
|
20
20
|
|
|
21
|
-
const ProviderContext = createContext(null)
|
|
22
21
|
function getSystemInfo () {
|
|
23
|
-
const windowDimensions =
|
|
24
|
-
const screenDimensions =
|
|
22
|
+
const windowDimensions = global.__mpxAppDimensionsInfo.window
|
|
23
|
+
const screenDimensions = global.__mpxAppDimensionsInfo.screen
|
|
25
24
|
return {
|
|
26
25
|
deviceOrientation: windowDimensions.width > windowDimensions.height ? 'landscape' : 'portrait',
|
|
27
26
|
size: {
|
|
@@ -172,8 +171,8 @@ const instanceProto = {
|
|
|
172
171
|
type: field
|
|
173
172
|
}
|
|
174
173
|
}
|
|
175
|
-
// 处理props
|
|
176
|
-
propsData[key] = field.value
|
|
174
|
+
// 处理props默认值,没有显式设置value时根据type获取默认值,与微信小程序原生行为保持一致
|
|
175
|
+
propsData[key] = hasOwn(field, 'value') ? field.value : getDefaultValueByType(field.type)
|
|
177
176
|
}
|
|
178
177
|
}
|
|
179
178
|
})
|
|
@@ -295,13 +294,18 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
295
294
|
instance[key] = method.bind(instance)
|
|
296
295
|
})
|
|
297
296
|
}
|
|
298
|
-
|
|
297
|
+
const loadParams = {}
|
|
299
298
|
if (type === 'page') {
|
|
300
299
|
const props = propsRef.current
|
|
301
300
|
instance.route = props.route.name
|
|
302
301
|
global.__mpxPagesMap = global.__mpxPagesMap || {}
|
|
303
302
|
global.__mpxPagesMap[props.route.key] = [instance, props.navigation]
|
|
304
303
|
setFocusedNavigation(props.navigation)
|
|
304
|
+
|
|
305
|
+
if (!global.__mpxAppHotLaunched && global.__mpxInitialRunParams) {
|
|
306
|
+
Object.assign(loadParams, global.__mpxInitialRunParams)
|
|
307
|
+
}
|
|
308
|
+
set(global.__mpxPageSizeCountMap, pageId, global.__mpxSizeCount)
|
|
305
309
|
// App onLaunch 在 Page created 之前执行
|
|
306
310
|
if (!global.__mpxAppHotLaunched && global.__mpxAppOnLaunch) {
|
|
307
311
|
global.__mpxAppOnLaunch(props.navigation)
|
|
@@ -310,17 +314,16 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
310
314
|
|
|
311
315
|
const proxy = instance.__mpxProxy = new MpxProxy(rawOptions, instance)
|
|
312
316
|
proxy.created()
|
|
313
|
-
|
|
314
317
|
if (type === 'page') {
|
|
315
318
|
const props = propsRef.current
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
if (isObject(
|
|
319
|
-
for (const key in
|
|
320
|
-
|
|
319
|
+
const decodedQuery = {}
|
|
320
|
+
const rawQuery = Object.assign({}, loadParams, props.route.params || {})
|
|
321
|
+
if (isObject(rawQuery)) {
|
|
322
|
+
for (const key in rawQuery) {
|
|
323
|
+
decodedQuery[key] = decodeURIComponent(rawQuery[key])
|
|
321
324
|
}
|
|
322
325
|
}
|
|
323
|
-
proxy.callHook(ONLOAD, [
|
|
326
|
+
proxy.callHook(ONLOAD, [rawQuery, decodedQuery])
|
|
324
327
|
}
|
|
325
328
|
|
|
326
329
|
Object.assign(proxy, {
|
|
@@ -375,9 +378,18 @@ const triggerPageStatusHook = (mpxProxy, event) => {
|
|
|
375
378
|
}
|
|
376
379
|
}
|
|
377
380
|
|
|
378
|
-
const triggerResizeEvent = (mpxProxy) => {
|
|
379
|
-
const
|
|
381
|
+
const triggerResizeEvent = (mpxProxy, sizeRef) => {
|
|
382
|
+
const oldSize = sizeRef.current.size
|
|
380
383
|
const systemInfo = getSystemInfo()
|
|
384
|
+
const newSize = systemInfo.size
|
|
385
|
+
|
|
386
|
+
if (oldSize && oldSize.windowWidth === newSize.windowWidth && oldSize.windowHeight === newSize.windowHeight) {
|
|
387
|
+
return
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
Object.assign(sizeRef.current, systemInfo)
|
|
391
|
+
|
|
392
|
+
const type = mpxProxy.options.__type__
|
|
381
393
|
const target = mpxProxy.target
|
|
382
394
|
mpxProxy.callHook(ONRESIZE, [systemInfo])
|
|
383
395
|
if (type === 'page') {
|
|
@@ -389,6 +401,8 @@ const triggerResizeEvent = (mpxProxy) => {
|
|
|
389
401
|
}
|
|
390
402
|
|
|
391
403
|
function usePageEffect (mpxProxy, pageId) {
|
|
404
|
+
const sizeRef = useRef(getSystemInfo())
|
|
405
|
+
|
|
392
406
|
useEffect(() => {
|
|
393
407
|
let unWatch
|
|
394
408
|
const hasShowHook = hasPageHook(mpxProxy, [ONSHOW, 'show'])
|
|
@@ -399,27 +413,40 @@ function usePageEffect (mpxProxy, pageId) {
|
|
|
399
413
|
unWatch = watch(() => pageStatusMap[pageId], (newVal) => {
|
|
400
414
|
if (newVal === 'show' || newVal === 'hide') {
|
|
401
415
|
triggerPageStatusHook(mpxProxy, newVal)
|
|
416
|
+
// 仅在尺寸确实变化时才触发resize事件
|
|
417
|
+
triggerResizeEvent(mpxProxy, sizeRef)
|
|
418
|
+
|
|
419
|
+
// 如果当前全局size与pagesize不一致,在show之后触发一次resize事件
|
|
420
|
+
if (newVal === 'show' && global.__mpxPageSizeCountMap[pageId] !== global.__mpxSizeCount) {
|
|
421
|
+
// 刷新__mpxPageSizeCountMap, 每个页面仅会执行一次,直接驱动render刷新
|
|
422
|
+
global.__mpxPageSizeCountMap[pageId] = global.__mpxSizeCount
|
|
423
|
+
}
|
|
402
424
|
} else if (/^resize/.test(newVal)) {
|
|
403
|
-
triggerResizeEvent(mpxProxy)
|
|
425
|
+
triggerResizeEvent(mpxProxy, sizeRef)
|
|
404
426
|
}
|
|
405
427
|
}, { sync: true })
|
|
406
428
|
}
|
|
407
429
|
}
|
|
408
430
|
return () => {
|
|
409
431
|
unWatch && unWatch()
|
|
432
|
+
del(global.__mpxPageSizeCountMap, pageId)
|
|
410
433
|
}
|
|
411
434
|
}, [])
|
|
412
435
|
}
|
|
413
436
|
|
|
414
437
|
let pageId = 0
|
|
415
438
|
const pageStatusMap = global.__mpxPageStatusMap = reactive({})
|
|
416
|
-
|
|
417
439
|
function usePageStatus (navigation, pageId) {
|
|
418
440
|
navigation.pageId = pageId
|
|
419
441
|
if (!hasOwn(pageStatusMap, pageId)) {
|
|
420
442
|
set(pageStatusMap, pageId, '')
|
|
421
443
|
}
|
|
422
444
|
useEffect(() => {
|
|
445
|
+
if (navigation.isFocused && navigation.isFocused()) {
|
|
446
|
+
Promise.resolve().then(() => {
|
|
447
|
+
pageStatusMap[pageId] = 'show'
|
|
448
|
+
})
|
|
449
|
+
}
|
|
423
450
|
const focusSubscription = navigation.addListener('focus', () => {
|
|
424
451
|
pageStatusMap[pageId] = 'show'
|
|
425
452
|
})
|
|
@@ -481,7 +508,17 @@ function getLayoutData (headerHeight) {
|
|
|
481
508
|
// 在横屏状态下 screen.height = window.height + bottomVirtualHeight
|
|
482
509
|
// 在正常状态 screen.height = window.height + bottomVirtualHeight + statusBarHeight
|
|
483
510
|
const isLandscape = screenDimensions.height < screenDimensions.width
|
|
484
|
-
|
|
511
|
+
let bottomVirtualHeight = 0
|
|
512
|
+
if (ReactNative.Platform.OS === 'android') {
|
|
513
|
+
if (isLandscape) {
|
|
514
|
+
bottomVirtualHeight = screenDimensions.height - windowDimensions.height
|
|
515
|
+
} else {
|
|
516
|
+
bottomVirtualHeight = initialWindowMetrics?.insets?.bottom || 0
|
|
517
|
+
if (typeof mpxGlobal.__mpx.config?.rnConfig?.getBottomVirtualHeight === 'function') {
|
|
518
|
+
bottomVirtualHeight = mpxGlobal.__mpx.config?.rnConfig?.getBottomVirtualHeight() || 0
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
485
522
|
return {
|
|
486
523
|
left: 0,
|
|
487
524
|
top: headerHeight,
|
|
@@ -497,7 +534,6 @@ function getLayoutData (headerHeight) {
|
|
|
497
534
|
|
|
498
535
|
export function PageWrapperHOC (WrappedComponent, pageConfig = {}) {
|
|
499
536
|
return function PageWrapperCom ({ navigation, route, ...props }) {
|
|
500
|
-
const rootRef = useRef(null)
|
|
501
537
|
const keyboardAvoidRef = useRef(null)
|
|
502
538
|
const intersectionObservers = useRef({})
|
|
503
539
|
const currentPageId = useMemo(() => ++pageId, [])
|
|
@@ -515,7 +551,7 @@ export function PageWrapperHOC (WrappedComponent, pageConfig = {}) {
|
|
|
515
551
|
navigation.layout = getLayoutData(headerHeight)
|
|
516
552
|
|
|
517
553
|
useEffect(() => {
|
|
518
|
-
const dimensionListener = ReactNative.Dimensions.addEventListener('change', ({ screen }) => {
|
|
554
|
+
const dimensionListener = ReactNative.Dimensions.addEventListener('change', ({ window, screen }) => {
|
|
519
555
|
navigation.layout = getLayoutData(headerHeight)
|
|
520
556
|
})
|
|
521
557
|
return () => dimensionListener?.remove()
|
|
@@ -525,6 +561,8 @@ export function PageWrapperHOC (WrappedComponent, pageConfig = {}) {
|
|
|
525
561
|
usePageStatus(navigation, currentPageId)
|
|
526
562
|
|
|
527
563
|
const withKeyboardAvoidingView = (element) => {
|
|
564
|
+
if (currentPageConfig.disableKeyboardAvoiding) return element
|
|
565
|
+
const MpxKeyboardAvoidingView = require('@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view').default
|
|
528
566
|
return createElement(KeyboardAvoidContext.Provider,
|
|
529
567
|
{
|
|
530
568
|
value: keyboardAvoidRef
|
|
@@ -549,11 +587,11 @@ export function PageWrapperHOC (WrappedComponent, pageConfig = {}) {
|
|
|
549
587
|
{
|
|
550
588
|
style: {
|
|
551
589
|
flex: 1,
|
|
552
|
-
|
|
590
|
+
// 页面容器背景色
|
|
591
|
+
backgroundColor: currentPageConfig?.backgroundColorContent || '#fff',
|
|
553
592
|
// 解决页面内有元素定位relative left为负值的时候,回退的时候还能看到对应元素问题
|
|
554
593
|
overflow: 'hidden'
|
|
555
|
-
}
|
|
556
|
-
ref: rootRef
|
|
594
|
+
}
|
|
557
595
|
},
|
|
558
596
|
createElement(RouteContext.Provider,
|
|
559
597
|
{
|