Skip to content

Commit

Permalink
Merge branch 'master' into feat-react-style
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] committed Aug 26, 2024
2 parents 97d8a1b + 547f7e0 commit 4d63a75
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 36 deletions.
1 change: 1 addition & 0 deletions packages/api-proxy/src/platform/api/app/index.android.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './index.web'
1 change: 1 addition & 0 deletions packages/api-proxy/src/platform/api/app/index.ios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './index.web'
9 changes: 5 additions & 4 deletions packages/api-proxy/src/platform/api/app/index.web.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isBrowser } from '../../../common/js'
import { isBrowser, isReact } from '@mpxjs/utils'

global.__mpxAppCbs = global.__mpxAppCbs || {
show: [],
hide: [],
Expand All @@ -7,7 +8,7 @@ global.__mpxAppCbs = global.__mpxAppCbs || {
}

function onError (callback) {
if (isBrowser) {
if (isBrowser || isReact) {
global.__mpxAppCbs.error.push(callback)
}
}
Expand All @@ -19,7 +20,7 @@ function offError (callback) {
}

function onAppShow (callback) {
if (isBrowser) {
if (isBrowser || isReact) {
global.__mpxAppCbs.show.push(callback)
}
}
Expand All @@ -31,7 +32,7 @@ function offAppShow (callback) {
}

function onAppHide (callback) {
if (isBrowser) {
if (isBrowser || isReact) {
global.__mpxAppCbs.hide.push(callback)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,50 @@
import * as Brightness from 'expo-brightness'
// 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)
// })
// }

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)
})
const { success, complete } = options
const result = {
errMsg: 'getScreenBrightness:ok'
}
successHandle(result, success, 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)
})
const { fail, complete } = options
const result = {
errMsg: 'setScreenBrightness:fail'
}
failHandle(result, fail, complete)
}

export {
Expand Down
52 changes: 52 additions & 0 deletions packages/core/src/platform/createApp.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ import { mergeLifecycle } from '../convertor/mergeLifecycle'
import * as wxLifecycle from '../platform/patch/wx/lifecycle'
import Mpx from '../index'
import { createElement, memo, useRef, useEffect } from 'react'
import * as ReactNative from 'react-native'
import { ref } from '../observer/ref'

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

function getOrientation (window = ReactNative.Dimensions.get('window')) {
return window.width > window.height ? 'landscape' : 'portrait'
}

function filterOptions (options, appData) {
const newOptions = {}
Object.keys(options).forEach(key => {
Expand Down Expand Up @@ -68,6 +74,14 @@ export default function createApp (option, config = {}) {
global.__navigationHelper.lastFailCallback = null
}
}

global.__mpxAppCbs = global.__mpxAppCbs || {
show: [],
hide: [],
error: []
}

global.__mpxAppFocusedState = ref('show')
global.__mpxOptionsMap[currentInject.moduleId] = memo(() => {
const instanceRef = useRef(null)
if (!instanceRef.current) {
Expand All @@ -85,7 +99,45 @@ export default function createApp (option, config = {}) {
}
global.__mpxEnterOptions = options
defaultOptions.onLaunch && defaultOptions.onLaunch.call(instance, options)
if (defaultOptions.onShow) {
defaultOptions.onShow.call(instance, options)
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))
}

const changeSubscription = ReactNative.AppState.addEventListener('change', (currentState) => {
if (currentState === 'active') {
global.__mpxAppCbs.show.forEach((cb) => {
cb(options)
global.__mpxAppFocusedState.value = 'show'
})
} else if (currentState === 'background') {
global.__mpxAppCbs.hide.forEach((cb) => {
cb()
global.__mpxAppFocusedState.value = 'hide'
})
}
})

let count = 0
let lastOrientation = getOrientation()
const resizeSubScription = ReactNative.Dimensions.addEventListener('change', ({ window }) => {
const orientation = getOrientation(window)
if (orientation === lastOrientation) return
lastOrientation = orientation
global.__mpxAppFocusedState.value = `resize${count++}`
})
return () => {
changeSubscription()
resizeSubScription && resizeSubScription.remove()
}
}, [])

return createElement(NavigationContainer,
{
ref: navigationRef,
Expand Down
139 changes: 134 additions & 5 deletions packages/core/src/platform/patch/react/getDefaultOptions.ios.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, createElement, memo, forwardRef, useImperativeHandle, Fragment } from 'react'
import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, createElement, memo, forwardRef, useImperativeHandle, useContext, createContext, Fragment } from 'react'
import * as ReactNative from 'react-native'
import { ReactiveEffect } from '../../../observer/effect'
import { watch } from '../../../observer/watch'
import { reactive, set } from '../../../observer/reactive'
import { hasOwn, isFunction, noop, isObject, error, getByPath, collectDataset } from '@mpxjs/utils'
import MpxProxy from '../../../core/proxy'
import { BEFOREUPDATE, UPDATED, ONLOAD } from '../../../core/innerLifecycle'
import { BEFOREUPDATE, ONLOAD, UPDATED, ONSHOW, ONHIDE, ONRESIZE } from '../../../core/innerLifecycle'
import mergeOptions from '../../../core/mergeOptions'
import { queueJob } from '../../../observer/scheduler'
import { createSelectorQuery } from '@mpxjs/api-proxy'

function getSystemInfo () {
const window = ReactNative.Dimensions.get('window')
const screen = ReactNative.Dimensions.get('screen')
return {
deviceOrientation: window.width > window.height ? 'landscape' : 'portrait',
size: {
screenWidth: screen.width,
screenHeight: screen.height,
windowWidth: window.width,
windowHeight: window.height
}
}
}

function getRootProps (props) {
const rootProps = {}
for (const key in props) {
Expand Down Expand Up @@ -120,8 +136,7 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
},
triggerEvent (eventName, eventDetail) {
const props = propsRef.current
const handlerName = eventName.replace(/^./, matched => matched.toUpperCase()).replace(/-([a-z])/g, (match, p1) => p1.toUpperCase())
const handler = props && (props['bind' + handlerName] || props['catch' + handlerName] || props['capture-bind' + handlerName] || props['capture-catch' + handlerName])
const handler = props && (props['bind' + eventName] || props['catch' + eventName] || props['capture-bind' + eventName] || props['capture-catch' + eventName])
if (handler && typeof handler === 'function') {
const timeStamp = +new Date()
const dataset = collectDataset(props)
Expand Down Expand Up @@ -216,6 +231,105 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
return instance
}

function hasPageHook (mpxProxy, hookNames) {
const options = mpxProxy.options
const type = options.__type__
return hookNames.some(h => {
if (mpxProxy.hasHook(h)) {
return true
}
if (type === 'page') {
return isFunction(options.methods && options.methods[h])
} else if (type === 'component') {
return options.pageLifetimes && isFunction(options.pageLifetimes[h])
}
return false
})
}

const routeContext = createContext(null)

const triggerPageStatusHook = (mpxProxy, event) => {
mpxProxy.callHook(event === 'show' ? ONSHOW : ONHIDE)
const pageLifetimes = mpxProxy.options.pageLifetimes
if (pageLifetimes) {
const instance = mpxProxy.target
isFunction(pageLifetimes[event]) && pageLifetimes[event].call(instance)
}
}

const triggerResizeEvent = (mpxProxy) => {
const type = mpxProxy.options.__type__
const systemInfo = getSystemInfo()
const target = mpxProxy.target
mpxProxy.callHook(ONRESIZE, [systemInfo])
if (type === 'page') {
target.onResize && target.onResize(systemInfo)
} else {
const pageLifetimes = mpxProxy.options.pageLifetimes
pageLifetimes && isFunction(pageLifetimes.resize) && pageLifetimes.resize.call(target, systemInfo)
}
}

function usePageContext (mpxProxy) {
const { routeName } = useContext(routeContext) || {}

useEffect(() => {
let unWatch
const hasShowHook = hasPageHook(mpxProxy, [ONSHOW, 'show'])
const hasHideHook = hasPageHook(mpxProxy, [ONHIDE, 'hide'])
const hasResizeHook = hasPageHook(mpxProxy, [ONRESIZE, 'resize'])
if (hasShowHook || hasHideHook || hasResizeHook) {
if (hasOwn(pageStatusContext, routeName)) {
unWatch = watch(() => pageStatusContext[routeName], (newVal) => {
if (newVal === 'show' || newVal === 'hide') {
triggerPageStatusHook(mpxProxy, newVal)
} else if (/^resize/.test(newVal)) {
triggerResizeEvent(mpxProxy)
}
})
}
}

return () => {
unWatch && unWatch()
}
}, [])
}

const pageStatusContext = reactive({})
function setPageStatus (routeName, val) {
set(pageStatusContext, routeName, val)
}

function usePageStatus (navigation, route) {
let isFocused = true
setPageStatus(route.name, '')
useEffect(() => {
setPageStatus(route.name, 'show')
const focusSubscription = navigation.addListener('focus', () => {
setPageStatus(route.name, 'show')
isFocused = true
})
const blurSubscription = navigation.addListener('blur', () => {
setPageStatus(route.name, 'hide')
isFocused = false
})

const unWatchAppFocusedState = watch(global.__mpxAppFocusedState, (value) => {
if (isFocused) {
setPageStatus(route.name, value)
}
})

return () => {
focusSubscription()
blurSubscription()
unWatchAppFocusedState()
}
}, [navigation])
}

export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
rawOptions = mergeOptions(rawOptions, type, false)
const components = Object.assign({}, rawOptions.components, currentInject.getComponents())
Expand Down Expand Up @@ -248,6 +362,8 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
proxy.propsUpdated()
}

usePageContext(proxy)

useEffect(() => {
if (proxy.pendingUpdatedFlag) {
proxy.pendingUpdatedFlag = false
Expand All @@ -274,6 +390,8 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
const { Provider } = global.__navigationHelper
const pageConfig = Object.assign({}, global.__mpxPageConfig, currentInject.pageConfig)
const Page = ({ navigation, route }) => {
usePageStatus(navigation, route)

useLayoutEffect(() => {
navigation.setOptions({
headerTitle: pageConfig.navigationBarTitleText || '',
Expand All @@ -293,7 +411,18 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
backgroundColor: pageConfig.backgroundColor || '#ffffff'
}
},
createElement(defaultOptions, { navigation, route, pageConfig })
createElement(routeContext.Provider,
{
value: { routeName: route.name }
},
createElement(defaultOptions,
{
navigation,
route,
pageConfig
}
)
)
)
)
}
Expand Down

0 comments on commit 4d63a75

Please sign in to comment.