Skip to content

Commit

Permalink
Merge branch 'master' into fix-checkbox-web
Browse files Browse the repository at this point in the history
  • Loading branch information
yandadaFreedom authored Jan 8, 2025
2 parents 26403ac + 53b8e08 commit 9d9b255
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 79 deletions.
2 changes: 1 addition & 1 deletion packages/api-proxy/src/platform/api/system/index.web.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ const getLaunchOptionsSync = function () {
throwSSRWarning('getLaunchOptionsSync API is running in non browser environments')
return
}
return global.__mpxEnterOptions || {}
return global.__mpxLaunchOptions || {}
}

export {
Expand Down
11 changes: 2 additions & 9 deletions packages/api-proxy/src/platform/api/system/rnSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,11 @@ const getWindowInfo = function () {
}

const getLaunchOptionsSync = function () {
const options = global.__mpxEnterOptions || {}
const { path, scene, query } = options
return {
path,
scene,
query
}
return global.__mpxLaunchOptions || {}
}

const getEnterOptionsSync = function () {
const result = getLaunchOptionsSync()
return result
return global.__mpxEnterOptions || {}
}

export {
Expand Down
59 changes: 25 additions & 34 deletions packages/core/src/platform/createApp.ios.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import transferOptions from '../core/transferOptions'
import builtInKeysMap from './patch/builtInKeysMap'
import { makeMap, spreadProp, getFocusedNavigation, hasOwn, extend } from '@mpxjs/utils'
import { makeMap, spreadProp, getFocusedNavigation, hasOwn } from '@mpxjs/utils'
import { mergeLifecycle } from '../convertor/mergeLifecycle'
import { LIFECYCLE } from '../platform/patch/lifecycle/index'
import Mpx from '../index'
import { createElement, memo, useRef, useEffect } from 'react'
import * as ReactNative from 'react-native'
import { Image } from 'react-native'
import { ref } from '../observer/ref'

const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app)

Expand All @@ -30,22 +29,24 @@ function filterOptions (options, appData) {
return newOptions
}

function createAppInstance (appData) {
return extend({}, Mpx.prototype, appData)
}

export default function createApp (option, config = {}) {
export default function createApp (options) {
const appData = {}

const { NavigationContainer, createStackNavigator, SafeAreaProvider } = global.__navigationHelper
// app选项目前不需要进行转换
const { rawOptions, currentInject } = transferOptions(option, 'app', false)
const { rawOptions, currentInject } = transferOptions(options, 'app', false)
const defaultOptions = filterOptions(spreadProp(rawOptions, 'methods'), appData)
defaultOptions.onAppInit && defaultOptions.onAppInit()
// 在页面script执行前填充getApp()
global.getApp = function () {
return appData
}

defaultOptions.onShow && global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(appData))
defaultOptions.onHide && global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(appData))
defaultOptions.onError && global.__mpxAppCbs.error.push(defaultOptions.onError.bind(appData))
defaultOptions.onUnhandledRejection && global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(appData))
defaultOptions.onAppInit && defaultOptions.onAppInit()

const pages = currentInject.getPages() || {}
const firstPage = currentInject.firstPage
const Stack = createStackNavigator()
Expand Down Expand Up @@ -82,55 +83,43 @@ export default function createApp (option, config = {}) {
}

global.__mpxAppLaunched = false

global.__mpxAppFocusedState = ref('show')
global.__mpxAppHotLaunched = false
global.__mpxOptionsMap[currentInject.moduleId] = memo((props) => {
const instanceRef = useRef(null)
if (!instanceRef.current) {
instanceRef.current = createAppInstance(appData)
}
const instance = instanceRef.current
const initialRouteRef = useRef({
initialRouteName: firstPage,
initialParams: {}
})

if (!global.__mpxAppLaunched) {
if (!global.__mpxAppHotLaunched) {
const { initialRouteName, initialParams } = Mpx.config.rnConfig.parseAppProps?.(props) || {}
initialRouteRef.current.initialRouteName = initialRouteName || initialRouteRef.current.initialRouteName
initialRouteRef.current.initialParams = initialParams || initialRouteRef.current.initialParams

global.__mpxAppOnLaunch = (navigation) => {
global.__mpxAppLaunched = true
const state = navigation.getState()
Mpx.config.rnConfig.onStateChange?.(state)
const current = state.routes[state.index]
global.__mpxEnterOptions = {
const options = {
path: current.name,
query: current.params,
scene: 0,
shareTicket: '',
referrerInfo: {}
}
defaultOptions.onLaunch && defaultOptions.onLaunch.call(instance, global.__mpxEnterOptions)
defaultOptions.onShow && defaultOptions.onShow.call(instance, global.__mpxEnterOptions)
global.__mpxEnterOptions = options
if (!global.__mpxAppLaunched) {
global.__mpxLaunchOptions = options
defaultOptions.onLaunch && defaultOptions.onLaunch.call(appData, options)
}
global.__mpxAppCbs.show.forEach((cb) => {
cb(options)
})
global.__mpxAppLaunched = true
global.__mpxAppHotLaunched = true
}
}

useEffect(() => {
if (defaultOptions.onShow) {
global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(instance))
}
if (defaultOptions.onHide) {
global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(instance))
}
if (defaultOptions.onError) {
global.__mpxAppCbs.error.push(defaultOptions.onError.bind(instance))
}
if (defaultOptions.onUnhandledRejection) {
global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(instance))
}

const changeSubscription = ReactNative.AppState.addEventListener('change', (currentState) => {
if (currentState === 'active') {
let options = global.__mpxEnterOptions
Expand Down Expand Up @@ -177,6 +166,8 @@ export default function createApp (option, config = {}) {
return () => {
changeSubscription && changeSubscription.remove()
resizeSubScription && resizeSubScription.remove()
// 热启动情况下,app会被销毁重建,将__mpxAppHotLaunched重置保障路由等初始化逻辑正确执行
global.__mpxAppHotLaunched = false
}
}, [])

Expand Down
51 changes: 24 additions & 27 deletions packages/core/src/platform/createApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,23 @@ function filterOptions (options, appData) {
return newOptions
}

export default function createApp (option, config = {}) {
// 在App中挂载mpx对象供周边工具访问,如e2e测试
export default function createApp (options, config = {}) {
const appData = {}
// app选项目前不需要进行转换
const { rawOptions, currentInject } = transferOptions(options, 'app', false)
const builtInMixins = [{
// 在App中挂载mpx对象供周边工具访问,如e2e测试
getMpx () {
return Mpx
}
}]
const appData = {}
if (__mpx_mode__ === 'web') {
builtInMixins.push({
created () {
Object.assign(this, Mpx.prototype)
beforeCreate () {
// for vue provide vm access
Object.assign(this, appData)
},
created () {
const current = this.$root.$options?.router?.currentRoute || {}
const options = {
path: current.path && current.path.replace(/^\//, ''),
Expand All @@ -45,48 +49,41 @@ export default function createApp (option, config = {}) {
shareTicket: '',
referrerInfo: {}
}
// web不分冷启动和热启动
global.__mpxEnterOptions = options
this.$options.onLaunch && this.$options.onLaunch.call(this, options)
if (isBrowser) {
if (this.$options.onShow) {
this.$options.onShow.call(this, options)
global.__mpxAppCbs.show.push(this.$options.onShow.bind(this))
}
if (this.$options.onHide) {
global.__mpxAppCbs.hide.push(this.$options.onHide.bind(this))
}
if (this.$options.onError) {
global.__mpxAppCbs.error.push(this.$options.onError.bind(this))
}
if (this.$options.onUnhandledRejection) {
global.__mpxAppCbs.rejection.push(this.$options.onUnhandledRejection.bind(this))
}
}
global.__mpxLaunchOptions = options
rawOptions.onLaunch && rawOptions.onLaunch.call(appData, options)
global.__mpxAppCbs.show.forEach((cb) => {
cb(options)
})
}
})
} else {
builtInMixins.push({
onLaunch () {
Object.assign(this, Mpx.prototype)
initAppProvides(rawOptions.provide, this)
}
})
}
// app选项目前不需要进行转换
const { rawOptions, currentInject } = transferOptions(option, 'app', false)
rawOptions.mixins = builtInMixins
const defaultOptions = filterOptions(spreadProp(mergeOptions(rawOptions, 'app', false), 'methods'), appData)

if (__mpx_mode__ === 'web') {
global.__mpxOptionsMap = global.__mpxOptionsMap || {}
global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions
global.getApp = function () {
if (!isBrowser) {
console.error('[Mpx runtime error]: Dangerous API! global.getApp method is running in non browser environments')
}
return appData
}
if (isBrowser) {
defaultOptions.onShow && global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(appData))
defaultOptions.onHide && global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(appData))
defaultOptions.onError && global.__mpxAppCbs.error.push(defaultOptions.onError.bind(appData))
defaultOptions.onUnhandledRejection && global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(appData))
}
global.__mpxOptionsMap = global.__mpxOptionsMap || {}
global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions
} else {
initAppProvides(rawOptions)
defaultOptions.onAppInit && defaultOptions.onAppInit()
const ctor = config.customCtor || global.currentCtor || App
ctor(defaultOptions)
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/platform/export/inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ const providesMap = {
global.__mpxProvidesMap = providesMap

/** @internal createApp() 初始化应用层 scope provide */
export function initAppProvides (appOptions) {
const provideOpt = appOptions.provide
export function initAppProvides (provideOpt, instance) {
if (provideOpt) {
const provided = isFunction(provideOpt)
? callWithErrorHandling(provideOpt.bind(appOptions), appOptions, 'createApp provide function')
? callWithErrorHandling(provideOpt.bind(instance), instance, 'createApp provide function')
: provideOpt
if (isObject(provided)) {
providesMap.__app = provided
Expand Down
6 changes: 1 addition & 5 deletions packages/core/src/platform/patch/getDefaultOptions.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,14 +365,10 @@ function usePageStatus (navigation, pageId) {
const blurSubscription = navigation.addListener('blur', () => {
pageStatusMap[pageId] = 'hide'
})
const unWatchAppFocusedState = watch(global.__mpxAppFocusedState, (value) => {
pageStatusMap[pageId] = value
})

return () => {
focusSubscription()
blurSubscription()
unWatchAppFocusedState()
del(pageStatusMap, pageId)
}
}, [navigation])
Expand Down Expand Up @@ -442,7 +438,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {

useEffect(() => {
if (type === 'page') {
if (!global.__mpxAppLaunched && global.__mpxAppOnLaunch) {
if (!global.__mpxAppHotLaunched && global.__mpxAppOnLaunch) {
global.__mpxAppOnLaunch(props.navigation)
}
proxy.callHook(ONLOAD, [props.route.params || {}])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ViewStyle } from 'react-native'
import { FunctionComponent } from 'react'

type NumberVal = number | `${number}%`
type backgroundPositionList = ['left' | 'right', NumberVal, 'top' | 'bottom', NumberVal] | []

export type ExtendedViewStyle = ViewStyle & {
backgroundImage?: string
backgroundSize?: Array<NumberVal | 'auto' | 'contain' | 'cover'>
borderRadius?: string | number
backgroundPosition?: backgroundPositionList
[key: string]: any
transform?: {[key: string]: number | string}[]
}

export type ExtendedFunctionComponent = FunctionComponent & {
isCustomText?: boolean
}

export type AnyFunc = (...args: ReadonlyArray<any>) => any
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { MutableRefObject } from 'react'
import { NativeSyntheticEvent } from 'react-native'

type LayoutRef = MutableRefObject<any>

type SetTimeoutReturnType = ReturnType<typeof setTimeout>

type Props = Record<string, any>

type AdditionalProps = Record<string, any>;

type RemoveProps = string[];

type NativeTouchEvent = NativeSyntheticEvent<NativeEvent>

type Navigation = Record<string, any>

interface NativeEvent {
timestamp: number;
pageX: number;
pageY: number;
touches: TouchPoint[]
changedTouches: TouchPoint[]
}

interface TouchPoint {
identifier: number;
pageX: number;
pageY: number;
clientX: number;
clientY: number;
locationX?: number;
locationY?: number;
}

interface InnerRef {
startTimer: {
bubble: null | ReturnType<typeof setTimeout>;
capture: null | ReturnType<typeof setTimeout>;
};
mpxPressInfo: {
detail: {
x: number;
y: number;
};
};
}
interface UseInnerPropsConfig {
layoutRef: LayoutRef;
disableTouch?: boolean;
disableTap?: boolean
}
interface DataSetType {
[key: string]: string;
}

export {
NativeTouchEvent,
Props,
AdditionalProps,
RemoveProps,
UseInnerPropsConfig,
InnerRef,
LayoutRef,
SetTimeoutReturnType,
DataSetType,
Navigation
}

0 comments on commit 9d9b255

Please sign in to comment.