Skip to content

Commit

Permalink
改造逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
wangcuijuan committed Jan 21, 2025
1 parent 2abcd9c commit dc28f2f
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 93 deletions.
41 changes: 22 additions & 19 deletions packages/api-proxy/src/platform/api/toast/rnToast.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ import { View, Text, Image, StyleSheet, ActivityIndicator, Dimensions } from 're
import { successHandle, failHandle, getPageId, error } from '../../../common/js'
import Portal from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-portal/index'

let toastKey
let isLoadingShow
const dimensionsScreen = Dimensions.get('screen')
const screenHeight = dimensionsScreen.height
const contentTop = parseInt(screenHeight * 0.4)
let tId // show duration 计时id
const styles = StyleSheet.create({
toastContent: {
maxWidth: '60%',
Expand Down Expand Up @@ -53,7 +51,8 @@ const styles = StyleSheet.create({
marginTop: 10
}
})

const toastMap = new Map()
const timerMap = new Map()
function showToast (options = {}) {
const id = getPageId()
const { title, icon = 'success', image, duration = 1500, mask = false, success, fail, complete, isLoading } = options
Expand All @@ -65,6 +64,10 @@ function showToast (options = {}) {
failHandle(result, fail, complete)
return
}

const timeoutId = timerMap.get(id)
clearTimeout(timeoutId)
timerMap.delete(id)
let ToastView
const successPng = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFwAAABcAgMAAACegTrLAAAADFBMVEUAAAD////R0dHj4+PcME2AAAAAAXRSTlMAQObYZgAAANNJREFUSMft1FEKwkAMBNBGyBFyH4/gR8f+ehSPLtiyQ+wM2C8Rmp+WQN90N8tOZ/1/4SbbYfpp+sBVMqafgGQKs+FvkjF8GR6aj4M8NB+GT8OX5i+GT8OX4aH5MHwZHpoPw+c3fA0xGl/zYBrP92o8vwVwF3NO8tySjXmINQLAs/WX9S8bP9UGJUZSi8MAuUqsj75payPxuWn1BmrjewCCfAvA4Fmjvx8HQL4HiJEHeRmg5k2+B8gTFeRFwL7NzREB/sCKwsG7KN2VSb7XMp31i3oBatNdEForTOoAAAAASUVORK5CYII='
const errorPng = 'data:image/png;base64,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'
Expand All @@ -74,10 +77,6 @@ function showToast (options = {}) {
}
const pointerEvents = mask ? 'auto' : 'none'
isLoadingShow = isLoading
if (tId) {
clearTimeout(tId)
}
tId = null
if (image || icon === 'success' || icon === 'error') {
ToastView = <View style={styles.toastWrap} pointerEvents={pointerEvents}>
<View style={[styles.toastContent, styles.toastHasIcon]}>
Expand Down Expand Up @@ -107,15 +106,17 @@ function showToast (options = {}) {
</View>
}
try {
if (toastKey) {
Portal.remove(toastKey)
if (toastMap.get(id)) {
Portal.remove(toastMap.get(id))
toastMap.delete(id)
}
toastKey = Portal.add(ToastView, id)
const toastKey = Portal.add(ToastView, id)
toastMap.set(id, toastKey)
if (!isLoading) {
tId = setTimeout(() => {
Portal.remove(toastKey)
toastKey = null
const timeoutId = setTimeout(() => {
Portal.remove(toastMap.get(id))
}, duration)
timerMap.set(id, timeoutId)
}
const result = {
errMsg: 'showToast:ok'
Expand All @@ -130,15 +131,16 @@ function showToast (options = {}) {
}

function hideToast(options = {}) {
const id = getPageId()
const { noConflict = false, success, fail, complete } = options

if (isLoadingShow && noConflict) {
return
}
try {
if (toastKey) {
Portal.remove(toastKey)
toastKey = null
if (toastMap.get(id)) {
Portal.remove(toastMap.get(id))
toastMap.delete(id)
}
const result = {
errMsg: 'hideToast:ok'
Expand Down Expand Up @@ -175,15 +177,16 @@ function showLoading (options = {}) {
}

function hideLoading (options = {}) {
const id = getPageId()
const { noConflict = false, success, fail, complete } = options
if (!isLoadingShow && noConflict) {
return
}
isLoadingShow = false
try {
if (toastKey) {
Portal.remove(toastKey)
toastKey = null
if (toastMap.get(id)) {
Portal.remove(toastMap.get(id))
toastMap.delete(id)
}
const result = {
errMsg: 'hideLoading:ok'
Expand Down
11 changes: 1 addition & 10 deletions packages/webpack-plugin/lib/runtime/components/react/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,11 @@ export interface IntersectionObserver {
throttleMeasure: () => void
}
}
export interface PortalManagerContextValue {
mount: (key: number, children: React.ReactNode) => void
update: (key: number, children: React.ReactNode) => void
unmount: (key: number) => void,
portals: Array<{key: number, children: React.ReactNode}>
}

export interface PortalContextValue {
mount: (children: React.ReactNode, key?: number, id?: number) => number| undefined
mount: (children: React.ReactNode, key?: number | null, id?: number| null) => number| undefined
update: (key: number, children: React.ReactNode) => void
unmount: (key: number) => void
manager?: PortalManagerContextValue
}

export interface ScrollViewContextValue {
Expand Down Expand Up @@ -75,5 +68,3 @@ export const KeyboardAvoidContext = createContext<KeyboardAvoidContextValue | nu
export const ScrollViewContext = createContext<ScrollViewContextValue>({ gestureRef: null })

export const PortalContext = createContext<PortalContextValue>(null as any)

export const PortalManagerContext = createContext<PortalManagerContextValue| null>(null)
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
import { ReactNode } from 'react'
import { PortalContext, PortalContextValue } from '../context'
import { ReactNode, useContext } from 'react'
import { PortalContext } from '../context'
import PortalConsumer from './portal-consumer'
import { useNavigation } from '@react-navigation/native'
import PortalHost, { portal } from './portal-host'

export type PortalProps = {
/**
* Content of the `Portal`.
*/
children?: ReactNode
key?: string
manager?: PortalContextValue,
pageId?: number
}

const Portal = ({ children }:PortalProps): JSX.Element => {
const navigation = useNavigation()
const pageId = navigation?.pageId
return (
<PortalContext.Consumer>
{(manager) => (
<PortalConsumer manager={manager}>{children}</PortalConsumer>
)}
</PortalContext.Consumer>
)
const manager = useContext(PortalContext)
return <PortalConsumer manager={manager}>{children}</PortalConsumer>
}

Portal.Host = PortalHost
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { useEffect, useRef, ReactNode } from 'react'
import { PortalContextValue } from '../context'
import { useEffect, useRef, ReactNode, useContext } from 'react'
import { PortalContextValue, RouteContext } from '../context'

export type PortalConsumerProps = {
manager: PortalContextValue
children?: ReactNode
}
const PortalConsumer = ({ manager, children } :PortalConsumerProps): JSX.Element | null => {
const keyRef = useRef<any>(null)
const pageId = useContext(RouteContext)
useEffect(() => {
manager.update(keyRef.current, children)
}, [children])
Expand All @@ -16,7 +17,7 @@ const PortalConsumer = ({ manager, children } :PortalConsumerProps): JSX.Element
'Looks like you forgot to wrap your root component with `Provider` component from `@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-portal/index`.\n\n'
)
}
keyRef.current = manager.mount(children)
keyRef.current = manager.mount(children, null, pageId)
return () => {
manager.unmount(keyRef.current)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ import {
StyleSheet
} from 'react-native'
import PortalManager from './portal-manager'
import { useNavigation } from '@react-navigation/native'
import { PortalManagerContextValue, PortalContext } from '../context'
import { PortalContext } from '../context'

export type PortalHostProps = {
type PortalHostProps = {
children: ReactNode,
pageId: number
}

type addIdsMapsType = {
[key: number]: number[]
interface PortalManagerContextValue {
mount: (key: number, children: React.ReactNode) => void
update: (key: number, children: React.ReactNode) => void
unmount: (key: number) => void
}

export type Operation =
Expand Down Expand Up @@ -66,66 +67,46 @@ const PortalHost = ({ children, pageId } :PortalHostProps): JSX.Element => {
const _updateType = useRef<EventSubscription | null>(null)
const manager = useRef<PortalManagerContextValue | null>(null)
const queue = useRef<Array<{ type: string, key: number; children: ReactNode }>>([])
const _mount = (children: ReactNode, _key?: number, id?: number) => {
const mount = (children: ReactNode, _key?: number, id?: number) => {
if (id !== pageId) return
const key = _key || _nextKey.current++
if (!isMounted.current) {
queue.current.push({ type: 'mount', key, children })
} else if (manager.current) {
manager.current.mount(key, children)
}
return key
}

const _unmount = (key: number) => {
if (!isMounted.current) {
queue.current.push({ type: 'unmount', key, children })
} else if (manager.current) {
manager.current.unmount(key)
}
}

const _update = (key: number, children?: ReactNode) => {
if (!isMounted.current) {
const operation = { type: 'mount', key, children }
const index = queue.current.findIndex((q) => q.key === key)
if (index > -1) {
queue.current[index] = operation
} else {
queue.current.push(operation)
}
} else if (manager.current) {
manager.current.update(key, children)
}
}

const mount = (children: ReactNode, _key?: number) => {
const key = _key || _nextKey.current++
if (manager.current) {
manager.current.mount(key, children)
} else {
queue.current.push({ type: 'mount', key, children })
}
return key
}

const unmount = (key: number) => {
if (manager.current) {
manager.current.unmount(key)
} else {
queue.current.push({ type: 'unmount', key, children })
}
}

const update = (key: number, children?: ReactNode) => {
if (manager.current) {
manager.current.update(key, children)
} else {
const operation = { type: 'mount', key, children }
const index = queue.current.findIndex((q) => q.type === 'mount' && q.key === key)
if (index > -1) {
queue.current[index] = operation
} else {
queue.current.push(operation)
}
}
}

useMemo(() => {
_addType.current = TopViewEventEmitter.addListener(addType, _mount)
_removeType.current = TopViewEventEmitter.addListener(removeType, _unmount)
_updateType.current = TopViewEventEmitter.addListener(updateType, _update)
_addType.current = TopViewEventEmitter.addListener(addType, mount)
_removeType.current = TopViewEventEmitter.addListener(removeType, unmount)
_updateType.current = TopViewEventEmitter.addListener(updateType, update)
}, [])
const navigation = useNavigation()
useEffect(() => {
isMounted.current = true
while (queue.current.length && manager.current) {
const operation = queue.current.shift()
if (!operation) return
Expand All @@ -135,17 +116,14 @@ const PortalHost = ({ children, pageId } :PortalHostProps): JSX.Element => {
break
case 'unmount':
manager.current.unmount(operation.key)
break
}
}
const focusSubscription = navigation.addListener('focus', () => {
isMounted.current = true
})

return () => {
_addType.current?.remove()
_removeType.current?.remove()
_updateType.current?.remove()
focusSubscription()
}
}, [])
return (
Expand Down

0 comments on commit dc28f2f

Please sign in to comment.