@mpxjs/core 2.10.2 → 2.10.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/core",
3
- "version": "2.10.2",
3
+ "version": "2.10.3",
4
4
  "description": "mpx runtime core",
5
5
  "keywords": [
6
6
  "miniprogram",
@@ -109,5 +109,5 @@
109
109
  "url": "https://github.com/didi/mpx/issues"
110
110
  },
111
111
  "sideEffects": false,
112
- "gitHead": "4445de7c3ce29fb0166d3bb77a1a0460e41a32d3"
112
+ "gitHead": "043c9bc770ce9cc11f865bab67f46849ff573728"
113
113
  }
@@ -18,6 +18,10 @@ export default function transferOptions (options, type, needConvert = true) {
18
18
  if (!options.__nativeRender__) {
19
19
  options = mergeInjectedMixins(options, type)
20
20
  }
21
+ if (currentInject && currentInject.injectProperties) {
22
+ // 编译属性注入
23
+ options.properties = Object.assign({}, currentInject.injectProperties, options.properties)
24
+ }
21
25
  if (currentInject && currentInject.injectComputed) {
22
26
  // 编译计算属性注入
23
27
  options.computed = Object.assign({}, currentInject.injectComputed, options.computed)
@@ -195,7 +195,14 @@ export default function styleHelperMixin () {
195
195
 
196
196
  if (hide) {
197
197
  Object.assign(result, {
198
- display: 'none'
198
+ // display: 'none'
199
+ // RN下display:'none'容易引发未知异常问题,使用布局样式模拟
200
+ flex: 0,
201
+ height: 0,
202
+ width: 0,
203
+ padding: 0,
204
+ margin: 0,
205
+ overflow: 'hidden'
199
206
  })
200
207
  }
201
208
 
@@ -10,8 +10,8 @@ import { initAppProvides } from './export/inject'
10
10
 
11
11
  const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app)
12
12
 
13
- function getOrientation (window = ReactNative.Dimensions.get('window')) {
14
- return window.width > window.height ? 'landscape' : 'portrait'
13
+ function getPageSize (window = ReactNative.Dimensions.get('window')) {
14
+ return window.width + 'x' + window.height
15
15
  }
16
16
 
17
17
  function filterOptions (options, appData) {
@@ -56,16 +56,22 @@ export default function createApp (options) {
56
56
  const Stack = createStackNavigator()
57
57
  const getPageScreens = (initialRouteName, initialParams) => {
58
58
  return Object.entries(pages).map(([key, item]) => {
59
+ const options = {
60
+ // __mpxPageStatusMap 为编译注入的全局变量
61
+ headerShown: !(Object.assign({}, global.__mpxPageConfig, global.__mpxPageConfigsMap[key]).navigationStyle === 'custom')
62
+ }
59
63
  if (key === initialRouteName) {
60
64
  return createElement(Stack.Screen, {
61
65
  name: key,
62
66
  component: item,
63
- initialParams
67
+ initialParams,
68
+ options
64
69
  })
65
70
  }
66
71
  return createElement(Stack.Screen, {
67
72
  name: key,
68
- component: item
73
+ component: item,
74
+ options
69
75
  })
70
76
  })
71
77
  }
@@ -154,7 +160,9 @@ export default function createApp (options) {
154
160
  }
155
161
  } else if (currentState === 'inactive' || currentState === 'background') {
156
162
  global.__mpxAppCbs.hide.forEach((cb) => {
157
- cb()
163
+ cb({
164
+ reason: 3
165
+ })
158
166
  })
159
167
  const navigation = getFocusedNavigation()
160
168
  if (navigation && hasOwn(global.__mpxPageStatusMap, navigation.pageId)) {
@@ -164,17 +172,23 @@ export default function createApp (options) {
164
172
  })
165
173
 
166
174
  let count = 0
167
- let lastOrientation = getOrientation()
175
+ let lastPageSize = getPageSize()
168
176
  const resizeSubScription = ReactNative.Dimensions.addEventListener('change', ({ window }) => {
169
- const orientation = getOrientation(window)
170
- if (orientation === lastOrientation) return
171
- lastOrientation = orientation
177
+ const pageSize = getPageSize(window)
178
+ if (pageSize === lastPageSize) return
179
+ lastPageSize = pageSize
172
180
  const navigation = getFocusedNavigation()
173
181
  if (navigation && hasOwn(global.__mpxPageStatusMap, navigation.pageId)) {
174
182
  global.__mpxPageStatusMap[navigation.pageId] = `resize${count++}`
175
183
  }
176
184
  })
177
185
  return () => {
186
+ // todo 跳到原生页面或者其他rn bundle可以考虑使用reason 1/2进行模拟抹平
187
+ global.__mpxAppCbs.hide.forEach((cb) => {
188
+ cb({
189
+ reason: 0
190
+ })
191
+ })
178
192
  changeSubscription && changeSubscription.remove()
179
193
  resizeSubScription && resizeSubScription.remove()
180
194
  }
@@ -186,6 +200,9 @@ export default function createApp (options) {
186
200
  // headerBackButtonDisplayMode: 'minimal',
187
201
  headerBackTitleVisible: false,
188
202
  headerShadowVisible: false
203
+ // 整体切换native-stack时进行修改如下
204
+ // statusBarTranslucent: true,
205
+ // statusBarBackgroundColor: 'transparent'
189
206
  }
190
207
  if (__mpx_mode__ === 'ios') {
191
208
  // ios使用native-stack
@@ -194,8 +211,8 @@ export default function createApp (options) {
194
211
  navScreenOpts.headerBackImageSource = headerBackImageSource
195
212
  }
196
213
  } else {
197
- // 安卓上会出现导航条闪现的问题所以默认加headerShown false(stack版本, native-stack版本可以干掉)
198
- // iOS加上默认headerShown false的话会因为iOS根高度是screenHeight - useHeaderHeight()会导致出现渲染两次情况,因此iOS不加此默认值
214
+ // 安卓上会出现导航条闪现的问题所以默认加headerShown false(stack版本, native-stack版本可以干掉)
215
+ // iOS加上默认headerShown false的话会因为iOS根高度是screenHeight - useHeaderHeight()会导致出现渲染两次情况,因此iOS不加此默认值
199
216
  navScreenOpts.headerShown = false
200
217
  // 安卓和鸿蒙先用stack
201
218
  const headerBackImageProps = Mpx.config.rnConfig.headerBackImageProps || null
@@ -10,20 +10,19 @@ import mergeOptions from '../../core/mergeOptions'
10
10
  import { queueJob, hasPendingJob } from '../../observer/scheduler'
11
11
  import { createSelectorQuery, createIntersectionObserver } from '@mpxjs/api-proxy'
12
12
  import { IntersectionObserverContext, RouteContext, KeyboardAvoidContext } from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/context'
13
- import KeyboardAvoidingView from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/KeyboardAvoidingView'
13
+ import MpxKeyboardAvoidingView from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view'
14
14
 
15
15
  const ProviderContext = createContext(null)
16
-
16
+ const windowDimensions = ReactNative.Dimensions.get('window')
17
+ const screenDimensions = ReactNative.Dimensions.get('screen')
17
18
  function getSystemInfo () {
18
- const window = ReactNative.Dimensions.get('window')
19
- const screen = ReactNative.Dimensions.get('screen')
20
19
  return {
21
- deviceOrientation: window.width > window.height ? 'landscape' : 'portrait',
20
+ deviceOrientation: windowDimensions.width > windowDimensions.height ? 'landscape' : 'portrait',
22
21
  size: {
23
- screenWidth: screen.width,
24
- screenHeight: screen.height,
25
- windowWidth: window.width,
26
- windowHeight: window.height
22
+ screenWidth: screenDimensions.width,
23
+ screenHeight: screenDimensions.height,
24
+ windowWidth: windowDimensions.width,
25
+ windowHeight: windowDimensions.height
27
26
  }
28
27
  }
29
28
  }
@@ -46,7 +45,9 @@ function createEffect (proxy, components) {
46
45
  if (!tagName) return null
47
46
  if (tagName === 'block') return Fragment
48
47
  const appComponents = global.__getAppComponents?.() || {}
49
- return components[tagName] || appComponents[tagName] || getByPath(ReactNative, tagName)
48
+ const generichash = proxy.target.generichash || ''
49
+ const genericComponents = global.__mpxGenericsMap[generichash] || noop
50
+ return components[tagName] || genericComponents(tagName) || appComponents[tagName] || getByPath(ReactNative, tagName)
50
51
  }
51
52
  const innerCreateElement = (type, ...rest) => {
52
53
  if (!type) return null
@@ -440,6 +441,8 @@ const checkRelation = (options) => {
440
441
  }
441
442
  }
442
443
 
444
+ // 临时用来存储安卓底部(iOS没有这个)的高度(虚拟按键等高度)根据第一次进入推算
445
+ let bottomVirtualHeight = null
443
446
  export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
444
447
  rawOptions = mergeOptions(rawOptions, type, false)
445
448
  const components = Object.assign({}, rawOptions.components, currentInject.getComponents())
@@ -586,9 +589,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
586
589
  })
587
590
  usePageStatus(navigation, currentPageId)
588
591
  useLayoutEffect(() => {
589
- const isCustom = pageConfig.navigationStyle === 'custom'
590
592
  navigation.setOptions({
591
- headerShown: !isCustom,
592
593
  title: pageConfig.navigationBarTitleText?.trim() || '',
593
594
  headerStyle: {
594
595
  backgroundColor: pageConfig.navigationBarBackgroundColor || '#000000'
@@ -596,29 +597,56 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
596
597
  headerTintColor: pageConfig.navigationBarTextStyle || 'white'
597
598
  })
598
599
 
600
+ // TODO 此部分内容在native-stack可删除,用setOptions设置
599
601
  if (__mpx_mode__ === 'android') {
600
602
  ReactNative.StatusBar.setBarStyle(pageConfig.barStyle || 'dark-content')
601
- ReactNative.StatusBar.setTranslucent(isCustom) // 控制statusbar是否占位
602
- const color = isCustom ? 'transparent' : pageConfig.statusBarColor
603
- color && ReactNative.StatusBar.setBackgroundColor(color)
603
+ ReactNative.StatusBar.setTranslucent(true) // 控制statusbar是否占位
604
+ ReactNative.StatusBar.setBackgroundColor('transparent')
604
605
  }
605
606
  }, [])
606
607
 
607
608
  const rootRef = useRef(null)
608
609
  const keyboardAvoidRef = useRef(null)
609
- useEffect(() => {
610
- setTimeout(() => {
611
- rootRef.current?.measureInWindow((x, y, width, height) => {
612
- navigation.layout = { x, y, width, height }
613
- })
614
- }, 100)
615
- }, [])
610
+ const headerHeight = useHeaderHeight()
611
+ const onLayout = () => {
612
+ if (__mpx_mode__ === 'ios') {
613
+ navigation.layout = {
614
+ x: 0,
615
+ y: headerHeight,
616
+ width: windowDimensions.width,
617
+ height: screenDimensions.height - headerHeight
618
+ }
619
+ } else {
620
+ if (bottomVirtualHeight === null) {
621
+ rootRef.current?.measureInWindow((height) => {
622
+ // 沉浸模式的计算方式
623
+ bottomVirtualHeight = screenDimensions.height - height - headerHeight
624
+ // 非沉浸模式(translucent=true)计算方式, 现在默认是全用沉浸模式,所以先不算这个
625
+ // bottomVirtualHeight = windowDimensions.height - height - headerHeight
626
+ navigation.layout = {
627
+ x: 0,
628
+ y: headerHeight,
629
+ width: windowDimensions.width,
630
+ height: height
631
+ }
632
+ })
633
+ } else {
634
+ navigation.layout = {
635
+ x: 0,
636
+ y: headerHeight, // 这个y值
637
+ width: windowDimensions.width,
638
+ // 后续页面的layout是通过第一次路由进入时候推算出来的底部区域来推算出来的
639
+ height: screenDimensions.height - bottomVirtualHeight - headerHeight
640
+ }
641
+ }
642
+ }
643
+ }
616
644
  const withKeyboardAvoidingView = (element) => {
617
645
  return createElement(KeyboardAvoidContext.Provider,
618
646
  {
619
647
  value: keyboardAvoidRef
620
648
  },
621
- createElement(KeyboardAvoidingView,
649
+ createElement(MpxKeyboardAvoidingView,
622
650
  {
623
651
  style: {
624
652
  flex: 1
@@ -652,7 +680,9 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
652
680
  flex: 1,
653
681
  backgroundColor: pageConfig.backgroundColor || '#ffffff'
654
682
  },
655
- ref: rootRef
683
+ ref: rootRef,
684
+ // 测试过了 键盘拉起后不会重新触发onLayout
685
+ onLayout
656
686
  },
657
687
  createElement(RouteContext.Provider,
658
688
  {