From 9a856b2a22a0dfa088ab92e5f51d52b68c8c2b8e Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Mon, 25 Nov 2024 14:42:08 +0800 Subject: [PATCH 01/20] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=85=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 58 +++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 8a212a432b..93a2ff353c 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -53,6 +53,10 @@ interface MovableViewProps { bindvtouchmove?: (event: NativeSyntheticEvent) => void; catchhtouchmove?: (event: NativeSyntheticEvent) => void; catchvtouchmove?: (event: NativeSyntheticEvent) => void; + bindlongpress?: (event: NativeSyntheticEvent) => void; + catchlongpress?: (event: NativeSyntheticEvent) => void; + bindtap?: (event: NativeSyntheticEvent) => void; + catchtap?: (event: NativeSyntheticEvent) => void; onLayout?: (event: LayoutChangeEvent) => void; 'out-of-bounds'?: boolean; 'wait-for'?: Array; @@ -108,7 +112,11 @@ const _MovableView = forwardRef, MovableViewP catchvtouchmove, catchtouchmove, bindtouchend, - catchtouchend + catchtouchend, + bindlongpress, + catchlongpress, + bindtap, + catchtap } = props const { @@ -139,6 +147,8 @@ const _MovableView = forwardRef, MovableViewP const yInertialMotion = useSharedValue(false) const isFirstTouch = useSharedValue(true) const touchEvent = useSharedValue('') + const startTimer = useSharedValue(null) + const needTap = useSharedValue(true) const MovableAreaLayout = useContext(MovableAreaContext) @@ -384,9 +394,38 @@ const _MovableView = forwardRef, MovableViewP bindtouchend && runOnJS(bindtouchend)(e) catchtouchend && runOnJS(catchtouchend)(e) } + + const handleTriggerPress = (e: any) => { + 'worklet' + extendEvent(e) + bindlongpress && runOnJS(bindlongpress)(e) + catchlongpress && runOnJS(catchlongpress)(e) + } + + const handleTriggerTap = (e: any) => { + 'worklet' + extendEvent(e) + bindtap && runOnJS(bindtap)(e) + catchtap && runOnJS(catchtap)(e) + } + + const checkIsNeedTap = (e: NativeTouchEvent) => { + const tapDetailInfo = startPosition.value || { x: 0, y: 0 } + const nativeEvent = e.nativeEvent + const currentPageX = nativeEvent.changedTouches[0].x + const currentPageY = nativeEvent.changedTouches[0].y + if (Math.abs(currentPageX - tapDetailInfo.x) > 1 || Math.abs(currentPageY - tapDetailInfo.y) > 1) { + needTap.value = false + startTimer.value && clearTimeout(startTimer.value) + startTimer.value = null + } + } + const gesturePan = Gesture.Pan() .onTouchesDown((e: GestureTouchEvent) => { 'worklet' + startTimer.value = null + needTap.value = true const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } isMoving.value = false startPosition.value = { @@ -394,9 +433,16 @@ const _MovableView = forwardRef, MovableViewP y: changedTouches.y } handleTriggerStart(e) + if (catchlongpress || bindlongpress) { + startTimer.value = setTimeout(() => { + needTap.value = false + handleTriggerPress(e) + }, 350) + } }) .onTouchesMove((e: GestureTouchEvent) => { 'worklet' + checkIsNeedTap(e) isMoving.value = true const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } if (isFirstTouch.value) { @@ -428,9 +474,13 @@ const _MovableView = forwardRef, MovableViewP }) .onTouchesUp((e: GestureTouchEvent) => { 'worklet' + checkIsNeedTap(e) isFirstTouch.value = true isMoving.value = false handleTriggerEnd(e) + if (needTap.value) { + handleTriggerTap(e) + } if (disabled) return if (!inertia) { const { x, y } = checkBoundaryPosition({ positionX: offsetX.value, positionY: offsetY.value }) @@ -500,9 +550,9 @@ const _MovableView = forwardRef, MovableViewP const injectCatchEvent = (props: Record) => { const eventHandlers: Record = {} const catchEventList = [ - { name: 'onTouchStart', value: ['catchtouchstart'] }, - { name: 'onTouchMove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove'] }, - { name: 'onTouchEnd', value: ['catchtouchend'] } + { name: 'onTouchStart', value: ['catchtouchstart', 'catchtap', 'catchlongpress'] }, + { name: 'onTouchMove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove', 'catchtap', 'catchlongpress'] }, + { name: 'onTouchEnd', value: ['catchtouchend', 'catchtap', 'catchlongpress'] } ] catchEventList.forEach(event => { event.value.forEach(name => { From 7992028db1e9782bb3ce047d6e29f6abe94ce65e Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Mon, 25 Nov 2024 14:43:21 +0800 Subject: [PATCH 02/20] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=85=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/mpx-movable-view.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 93a2ff353c..2bdad7d1d9 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -409,11 +409,10 @@ const _MovableView = forwardRef, MovableViewP catchtap && runOnJS(catchtap)(e) } - const checkIsNeedTap = (e: NativeTouchEvent) => { + const checkIsNeedTap = (e: GestureTouchEvent) => { const tapDetailInfo = startPosition.value || { x: 0, y: 0 } - const nativeEvent = e.nativeEvent - const currentPageX = nativeEvent.changedTouches[0].x - const currentPageY = nativeEvent.changedTouches[0].y + const currentPageX = e.changedTouches[0].x + const currentPageY = e.changedTouches[0].y if (Math.abs(currentPageX - tapDetailInfo.x) > 1 || Math.abs(currentPageY - tapDetailInfo.y) > 1) { needTap.value = false startTimer.value && clearTimeout(startTimer.value) From 3f1668e617a187f7f21748349d5e2dea59747d0a Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Mon, 25 Nov 2024 19:37:41 +0800 Subject: [PATCH 03/20] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=85=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 2bdad7d1d9..7d653be7ba 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -43,20 +43,20 @@ interface MovableViewProps { disabled?: boolean; animation?: boolean; bindchange?: (event: unknown) => void; - bindtouchstart?: (event: NativeSyntheticEvent) => void; - catchtouchstart?: (event: NativeSyntheticEvent) => void; - bindtouchmove?: (event: NativeSyntheticEvent) => void; - catchtouchmove?: (event: NativeSyntheticEvent) => void; - catchtouchend?: (event: NativeSyntheticEvent) => void; - bindtouchend?: (event: NativeSyntheticEvent) => void; - bindhtouchmove?: (event: NativeSyntheticEvent) => void; - bindvtouchmove?: (event: NativeSyntheticEvent) => void; - catchhtouchmove?: (event: NativeSyntheticEvent) => void; - catchvtouchmove?: (event: NativeSyntheticEvent) => void; - bindlongpress?: (event: NativeSyntheticEvent) => void; - catchlongpress?: (event: NativeSyntheticEvent) => void; - bindtap?: (event: NativeSyntheticEvent) => void; - catchtap?: (event: NativeSyntheticEvent) => void; + bindtouchstart?: (event: GestureTouchEvent) => void; + catchtouchstart?: (event: GestureTouchEvent) => void; + bindtouchmove?: (event: GestureTouchEvent) => void; + catchtouchmove?: (event: GestureTouchEvent) => void; + catchtouchend?: (event: GestureTouchEvent) => void; + bindtouchend?: (event: GestureTouchEvent) => void; + bindhtouchmove?: (event:GestureTouchEvent) => void; + bindvtouchmove?: (event: GestureTouchEvent) => void; + catchhtouchmove?: (event: GestureTouchEvent) => void; + catchvtouchmove?: (event: GestureTouchEvent) => void; + bindlongpress?: (event: GestureTouchEvent) => void; + catchlongpress?: (event:GestureTouchEvent) => void; + bindtap?: (event: GestureTouchEvent) => void; + catchtap?: (event: GestureTouchEvent) => void; onLayout?: (event: LayoutChangeEvent) => void; 'out-of-bounds'?: boolean; 'wait-for'?: Array; @@ -395,13 +395,6 @@ const _MovableView = forwardRef, MovableViewP catchtouchend && runOnJS(catchtouchend)(e) } - const handleTriggerPress = (e: any) => { - 'worklet' - extendEvent(e) - bindlongpress && runOnJS(bindlongpress)(e) - catchlongpress && runOnJS(catchlongpress)(e) - } - const handleTriggerTap = (e: any) => { 'worklet' extendEvent(e) @@ -409,17 +402,30 @@ const _MovableView = forwardRef, MovableViewP catchtap && runOnJS(catchtap)(e) } + const clearStartTimer = () => { + startTimer.value && clearTimeout(startTimer.value) + startTimer.value = null + } + const checkIsNeedTap = (e: GestureTouchEvent) => { + 'worklet' const tapDetailInfo = startPosition.value || { x: 0, y: 0 } - const currentPageX = e.changedTouches[0].x - const currentPageY = e.changedTouches[0].y - if (Math.abs(currentPageX - tapDetailInfo.x) > 1 || Math.abs(currentPageY - tapDetailInfo.y) > 1) { + const currentX = e.changedTouches[0].x + const currentY = e.changedTouches[0].y + if ((Math.abs(currentX - tapDetailInfo.x) > 1 || Math.abs(currentY - tapDetailInfo.y) > 1) && (needTap.value || startTimer.value)) { needTap.value = false - startTimer.value && clearTimeout(startTimer.value) - startTimer.value = null + runOnJS(clearStartTimer)() } } + const handleLongPress = (e: GestureTouchEvent) => { + startTimer.value = setTimeout(() => { + needTap.value = false + bindlongpress && bindlongpress(e) + catchlongpress && catchlongpress(e) + }, 350) + } + const gesturePan = Gesture.Pan() .onTouchesDown((e: GestureTouchEvent) => { 'worklet' @@ -433,10 +439,7 @@ const _MovableView = forwardRef, MovableViewP } handleTriggerStart(e) if (catchlongpress || bindlongpress) { - startTimer.value = setTimeout(() => { - needTap.value = false - handleTriggerPress(e) - }, 350) + runOnJS(handleLongPress)(e) } }) .onTouchesMove((e: GestureTouchEvent) => { From f27e456ce7ce54a3746c948dbd230f5e3b10be2e Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Wed, 27 Nov 2024 16:34:22 +0800 Subject: [PATCH 04/20] chore: add event --- .../components/react/mpx-movable-view.tsx | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 7d653be7ba..8e69976707 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -358,14 +358,12 @@ const _MovableView = forwardRef, MovableViewP const gesture = useMemo(() => { const handleTriggerStart = (e: any) => { 'worklet' - extendEvent(e) bindtouchstart && runOnJS(bindtouchstart)(e) catchtouchstart && runOnJS(catchtouchstart)(e) } const handleTriggerMove = (e: any) => { 'worklet' - extendEvent(e) const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove const hasCatchTouchmove = !!catchhtouchmove || !!catchvtouchmove || !!catchtouchmove @@ -390,18 +388,24 @@ const _MovableView = forwardRef, MovableViewP const handleTriggerEnd = (e: any) => { 'worklet' - extendEvent(e) bindtouchend && runOnJS(bindtouchend)(e) catchtouchend && runOnJS(catchtouchend)(e) } const handleTriggerTap = (e: any) => { 'worklet' - extendEvent(e) bindtap && runOnJS(bindtap)(e) catchtap && runOnJS(catchtap)(e) } + const handleLongPress = (e: GestureTouchEvent) => { + startTimer.value = setTimeout(() => { + needTap.value = false + bindlongpress && bindlongpress(e) + catchlongpress && catchlongpress(e) + }, 350) + } + const clearStartTimer = () => { startTimer.value && clearTimeout(startTimer.value) startTimer.value = null @@ -414,29 +418,24 @@ const _MovableView = forwardRef, MovableViewP const currentY = e.changedTouches[0].y if ((Math.abs(currentX - tapDetailInfo.x) > 1 || Math.abs(currentY - tapDetailInfo.y) > 1) && (needTap.value || startTimer.value)) { needTap.value = false - runOnJS(clearStartTimer)() + if (catchlongpress || bindlongpress) { + runOnJS(clearStartTimer)() + } } } - const handleLongPress = (e: GestureTouchEvent) => { - startTimer.value = setTimeout(() => { - needTap.value = false - bindlongpress && bindlongpress(e) - catchlongpress && catchlongpress(e) - }, 350) - } - const gesturePan = Gesture.Pan() .onTouchesDown((e: GestureTouchEvent) => { 'worklet' + const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } startTimer.value = null needTap.value = true - const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } isMoving.value = false startPosition.value = { x: changedTouches.x, y: changedTouches.y } + extendEvent(e) handleTriggerStart(e) if (catchlongpress || bindlongpress) { runOnJS(handleLongPress)(e) @@ -444,13 +443,14 @@ const _MovableView = forwardRef, MovableViewP }) .onTouchesMove((e: GestureTouchEvent) => { 'worklet' + const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } checkIsNeedTap(e) isMoving.value = true - const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } if (isFirstTouch.value) { touchEvent.value = Math.abs(changedTouches.x - startPosition.value.x) > Math.abs(changedTouches.y - startPosition.value.y) ? 'htouchmove' : 'vtouchmove' isFirstTouch.value = false } + extendEvent(e) handleTriggerMove(e) if (disabled) return const changeX = changedTouches.x - startPosition.value.x @@ -476,13 +476,17 @@ const _MovableView = forwardRef, MovableViewP }) .onTouchesUp((e: GestureTouchEvent) => { 'worklet' - checkIsNeedTap(e) isFirstTouch.value = true isMoving.value = false + extendEvent(e) handleTriggerEnd(e) + checkIsNeedTap(e) if (needTap.value) { handleTriggerTap(e) } + if (catchlongpress || bindlongpress) { + runOnJS(clearStartTimer)() + } if (disabled) return if (!inertia) { const { x, y } = checkBoundaryPosition({ positionX: offsetX.value, positionY: offsetY.value }) From cfa5aefea77e25bc332f3cba6878ce8c59b93c65 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Wed, 27 Nov 2024 20:05:53 +0800 Subject: [PATCH 05/20] =?UTF-8?q?chore:=20=E4=BC=98=E5=8C=96=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 148 ++++++++++-------- 1 file changed, 82 insertions(+), 66 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 8e69976707..ee1e53e03e 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -33,6 +33,7 @@ import Animated, { useAnimatedReaction, withSpring } from 'react-native-reanimated' +import { collectDataset } from '@mpxjs/utils' interface MovableViewProps { children: ReactNode; @@ -42,6 +43,7 @@ interface MovableViewProps { y?: number; disabled?: boolean; animation?: boolean; + id?: string; bindchange?: (event: unknown) => void; bindtouchstart?: (event: GestureTouchEvent) => void; catchtouchstart?: (event: GestureTouchEvent) => void; @@ -49,12 +51,12 @@ interface MovableViewProps { catchtouchmove?: (event: GestureTouchEvent) => void; catchtouchend?: (event: GestureTouchEvent) => void; bindtouchend?: (event: GestureTouchEvent) => void; - bindhtouchmove?: (event:GestureTouchEvent) => void; + bindhtouchmove?: (event: GestureTouchEvent) => void; bindvtouchmove?: (event: GestureTouchEvent) => void; catchhtouchmove?: (event: GestureTouchEvent) => void; catchvtouchmove?: (event: GestureTouchEvent) => void; bindlongpress?: (event: GestureTouchEvent) => void; - catchlongpress?: (event:GestureTouchEvent) => void; + catchlongpress?: (event: GestureTouchEvent) => void; bindtap?: (event: GestureTouchEvent) => void; catchtap?: (event: GestureTouchEvent) => void; onLayout?: (event: LayoutChangeEvent) => void; @@ -163,10 +165,10 @@ const _MovableView = forwardRef, MovableViewP }) const hasSimultaneousHandlersChanged = prevSimultaneousHandlersRef.current.length !== (originSimultaneousHandlers?.length || 0) || - (originSimultaneousHandlers || []).some((handler, index) => handler !== prevSimultaneousHandlersRef.current[index]) + (originSimultaneousHandlers || []).some((handler, index) => handler !== prevSimultaneousHandlersRef.current[index]) const hasWaitForHandlersChanged = prevWaitForHandlersRef.current.length !== (waitFor?.length || 0) || - (waitFor || []).some((handler, index) => handler !== prevWaitForHandlersRef.current[index]) + (waitFor || []).some((handler, index) => handler !== prevWaitForHandlersRef.current[index]) if (hasSimultaneousHandlersChanged || hasWaitForHandlersChanged) { gestureSwitch.current = !gestureSwitch.current @@ -343,8 +345,7 @@ const _MovableView = forwardRef, MovableViewP props.onLayout && props.onLayout(e) } - const extendEvent = useCallback((e: any) => { - 'worklet' + const extendEvent = useCallback((e: any, obj?: Record) => { const touchArr = [e.changedTouches, e.allTouches] touchArr.forEach(touches => { touches && touches.forEach((item: { absoluteX: number; absoluteY: number; pageX: number; pageY: number }) => { @@ -352,65 +353,74 @@ const _MovableView = forwardRef, MovableViewP item.pageY = item.absoluteY }) }) - e.touches = e.allTouches - }, []) - - const gesture = useMemo(() => { - const handleTriggerStart = (e: any) => { - 'worklet' - bindtouchstart && runOnJS(bindtouchstart)(e) - catchtouchstart && runOnJS(catchtouchstart)(e) - } - - const handleTriggerMove = (e: any) => { - 'worklet' - const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove - const hasCatchTouchmove = !!catchhtouchmove || !!catchvtouchmove || !!catchtouchmove - - if (hasTouchmove) { - if (touchEvent.value === 'htouchmove') { - bindhtouchmove && runOnJS(bindhtouchmove)(e) - } else if (touchEvent.value === 'vtouchmove') { - bindvtouchmove && runOnJS(bindvtouchmove)(e) - } - bindtouchmove && runOnJS(bindtouchmove)(e) + Object.assign(e, { + touches: e.allTouches, + detail: { + x: e.changedTouches[0].absoluteX, + y: e.changedTouches[0].absoluteY + }, + currentTarget: { + id: props.id || '', + dataset: collectDataset(props), + offsetLeft: 0, + offsetTop: 0 } + }, obj) + }, []) - if (hasCatchTouchmove) { - if (touchEvent.value === 'htouchmove') { - catchhtouchmove && runOnJS(catchhtouchmove)(e) - } else if (touchEvent.value === 'vtouchmove') { - catchvtouchmove && runOnJS(catchvtouchmove)(e) - } - catchtouchmove && runOnJS(catchtouchmove)(e) - } - } - - const handleTriggerEnd = (e: any) => { - 'worklet' - bindtouchend && runOnJS(bindtouchend)(e) - catchtouchend && runOnJS(catchtouchend)(e) - } - - const handleTriggerTap = (e: any) => { - 'worklet' - bindtap && runOnJS(bindtap)(e) - catchtap && runOnJS(catchtap)(e) - } + const clearStartTimer = () => { + startTimer.value && clearTimeout(startTimer.value) + startTimer.value = null + } - const handleLongPress = (e: GestureTouchEvent) => { + const triggerStartOnJS = ({ e }: { e: GestureTouchEvent }) => { + extendEvent(e) + bindtouchstart && bindtouchstart(e) + catchtouchstart && catchtouchstart(e) + if (catchlongpress || bindlongpress) { startTimer.value = setTimeout(() => { needTap.value = false bindlongpress && bindlongpress(e) catchlongpress && catchlongpress(e) }, 350) } + } - const clearStartTimer = () => { - startTimer.value && clearTimeout(startTimer.value) - startTimer.value = null + const triggerMoveOnJS = ({ e, hasTouchmove, hasCatchTouchmove, touchEvent }: { e: GestureTouchEvent; hasTouchmove: boolean; hasCatchTouchmove: boolean; touchEvent: string }) => { + extendEvent(e) + if (hasTouchmove) { + if (touchEvent === 'htouchmove') { + bindhtouchmove && bindhtouchmove(e) + } else if (touchEvent === 'vtouchmove') { + bindvtouchmove && bindvtouchmove(e) + } + bindtouchmove && bindtouchmove(e) + } + + if (hasCatchTouchmove) { + if (touchEvent === 'htouchmove') { + catchhtouchmove && catchhtouchmove(e) + } else if (touchEvent === 'vtouchmove') { + catchvtouchmove && catchvtouchmove(e) + } + catchtouchmove && catchtouchmove(e) + } + } + + const triggerEndOnJS = ({ e }: { e: GestureTouchEvent }) => { + extendEvent(e) + bindtouchend && bindtouchend(e) + catchtouchend && catchtouchend(e) + if (needTap.value) { + bindtap && bindtap(e) + catchtap && catchtap(e) + } + if (catchlongpress || bindlongpress) { + clearStartTimer() } + } + const gesture = useMemo(() => { const checkIsNeedTap = (e: GestureTouchEvent) => { 'worklet' const tapDetailInfo = startPosition.value || { x: 0, y: 0 } @@ -424,6 +434,20 @@ const _MovableView = forwardRef, MovableViewP } } + const handleTriggerMove = (e: GestureTouchEvent) => { + 'worklet' + const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove + const hasCatchTouchmove = !!catchhtouchmove || !!catchvtouchmove || !!catchtouchmove + if (hasTouchmove || hasCatchTouchmove) { + runOnJS(triggerMoveOnJS)({ + e, + touchEvent: touchEvent.value, + hasTouchmove, + hasCatchTouchmove + }) + } + } + const gesturePan = Gesture.Pan() .onTouchesDown((e: GestureTouchEvent) => { 'worklet' @@ -435,22 +459,19 @@ const _MovableView = forwardRef, MovableViewP x: changedTouches.x, y: changedTouches.y } - extendEvent(e) - handleTriggerStart(e) - if (catchlongpress || bindlongpress) { - runOnJS(handleLongPress)(e) + if (bindtouchstart || catchtouchstart || bindlongpress || catchlongpress) { + runOnJS(triggerStartOnJS)({ e }) } }) .onTouchesMove((e: GestureTouchEvent) => { 'worklet' const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } - checkIsNeedTap(e) isMoving.value = true if (isFirstTouch.value) { touchEvent.value = Math.abs(changedTouches.x - startPosition.value.x) > Math.abs(changedTouches.y - startPosition.value.y) ? 'htouchmove' : 'vtouchmove' isFirstTouch.value = false } - extendEvent(e) + checkIsNeedTap(e) handleTriggerMove(e) if (disabled) return const changeX = changedTouches.x - startPosition.value.x @@ -478,14 +499,9 @@ const _MovableView = forwardRef, MovableViewP 'worklet' isFirstTouch.value = true isMoving.value = false - extendEvent(e) - handleTriggerEnd(e) checkIsNeedTap(e) - if (needTap.value) { - handleTriggerTap(e) - } - if (catchlongpress || bindlongpress) { - runOnJS(clearStartTimer)() + if (bindtouchend || catchtouchend || bindtap || catchtap) { + runOnJS(triggerEndOnJS)({ e }) } if (disabled) return if (!inertia) { From fb285a1265af70bd3377744df40fa5ed98217d88 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 19 Dec 2024 19:34:31 +0800 Subject: [PATCH 06/20] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E8=A7=A6=E5=8F=91=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 72 +++++-------------- 1 file changed, 18 insertions(+), 54 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index cf48d936af..4a1a37fe41 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -19,7 +19,7 @@ */ import { useEffect, forwardRef, ReactNode, useContext, useCallback, useRef, useMemo, createElement } from 'react' import { StyleSheet, NativeSyntheticEvent, View, LayoutChangeEvent } from 'react-native' -import { getCustomEvent } from './getInnerListeners' +import useInnerProps, { getCustomEvent } from './getInnerListeners' import useNodesRef, { HandlerRef } from './useNodesRef' import { MovableAreaContext } from './context' import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, GestureHandler, flatGesture, extendObject } from './utils' @@ -33,7 +33,7 @@ import Animated, { useAnimatedReaction, withSpring } from 'react-native-reanimated' -import { collectDataset } from '@mpxjs/utils' +import { collectDataset, noop } from '@mpxjs/utils' interface MovableViewProps { children: ReactNode; @@ -149,8 +149,6 @@ const _MovableView = forwardRef, MovableViewP const yInertialMotion = useSharedValue(false) const isFirstTouch = useSharedValue(true) const touchEvent = useSharedValue('') - const startTimer = useSharedValue(null) - const needTap = useSharedValue(true) const MovableAreaLayout = useContext(MovableAreaContext) @@ -368,22 +366,10 @@ const _MovableView = forwardRef, MovableViewP }, obj) }, []) - const clearStartTimer = () => { - startTimer.value && clearTimeout(startTimer.value) - startTimer.value = null - } - const triggerStartOnJS = ({ e }: { e: GestureTouchEvent }) => { extendEvent(e) bindtouchstart && bindtouchstart(e) catchtouchstart && catchtouchstart(e) - if (catchlongpress || bindlongpress) { - startTimer.value = setTimeout(() => { - needTap.value = false - bindlongpress && bindlongpress(e) - catchlongpress && catchlongpress(e) - }, 350) - } } const triggerMoveOnJS = ({ e, hasTouchmove, hasCatchTouchmove, touchEvent }: { e: GestureTouchEvent; hasTouchmove: boolean; hasCatchTouchmove: boolean; touchEvent: string }) => { @@ -411,29 +397,9 @@ const _MovableView = forwardRef, MovableViewP extendEvent(e) bindtouchend && bindtouchend(e) catchtouchend && catchtouchend(e) - if (needTap.value) { - bindtap && bindtap(e) - catchtap && catchtap(e) - } - if (catchlongpress || bindlongpress) { - clearStartTimer() - } } const gesture = useMemo(() => { - const checkIsNeedTap = (e: GestureTouchEvent) => { - 'worklet' - const tapDetailInfo = startPosition.value || { x: 0, y: 0 } - const currentX = e.changedTouches[0].x - const currentY = e.changedTouches[0].y - if ((Math.abs(currentX - tapDetailInfo.x) > 1 || Math.abs(currentY - tapDetailInfo.y) > 1) && (needTap.value || startTimer.value)) { - needTap.value = false - if (catchlongpress || bindlongpress) { - runOnJS(clearStartTimer)() - } - } - } - const handleTriggerMove = (e: GestureTouchEvent) => { 'worklet' const hasTouchmove = !!bindhtouchmove || !!bindvtouchmove || !!bindtouchmove @@ -452,14 +418,12 @@ const _MovableView = forwardRef, MovableViewP .onTouchesDown((e: GestureTouchEvent) => { 'worklet' const changedTouches = e.changedTouches[0] || { x: 0, y: 0 } - startTimer.value = null - needTap.value = true isMoving.value = false startPosition.value = { x: changedTouches.x, y: changedTouches.y } - if (bindtouchstart || catchtouchstart || bindlongpress || catchlongpress) { + if (bindtouchstart || catchtouchstart) { runOnJS(triggerStartOnJS)({ e }) } }) @@ -471,7 +435,6 @@ const _MovableView = forwardRef, MovableViewP touchEvent.value = Math.abs(changedTouches.x - startPosition.value.x) > Math.abs(changedTouches.y - startPosition.value.y) ? 'htouchmove' : 'vtouchmove' isFirstTouch.value = false } - checkIsNeedTap(e) handleTriggerMove(e) if (disabled) return const changeX = changedTouches.x - startPosition.value.x @@ -499,7 +462,6 @@ const _MovableView = forwardRef, MovableViewP 'worklet' isFirstTouch.value = true isMoving.value = false - checkIsNeedTap(e) if (bindtouchend || catchtouchend || bindtap || catchtap) { runOnJS(triggerEndOnJS)({ e }) } @@ -526,8 +488,8 @@ const _MovableView = forwardRef, MovableViewP }) .onFinalize((e: GestureStateChangeEvent) => { 'worklet' - if (!inertia || disabled || !animation) return isMoving.value = false + if (!inertia || disabled || !animation) return if (direction === 'horizontal' || direction === 'all') { xInertialMotion.value = true offsetX.value = withDecay({ @@ -572,32 +534,34 @@ const _MovableView = forwardRef, MovableViewP const injectCatchEvent = (props: Record) => { const eventHandlers: Record = {} const catchEventList = [ - { name: 'onTouchStart', value: ['catchtouchstart', 'catchtap', 'catchlongpress'] }, - { name: 'onTouchMove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove', 'catchtap', 'catchlongpress'] }, - { name: 'onTouchEnd', value: ['catchtouchend', 'catchtap', 'catchlongpress'] } + { name: 'bindtouchstart', value: ['bindtouchstart'] }, + { name: 'bindtouchmove', value: ['bindtouchmove', 'bindvtouchmove', 'bindhtouchmove'] }, + { name: 'bindtouchend', value: ['bindtouchend'] }, + { name: 'catchtouchstart', value: ['catchtouchstart'] }, + { name: 'catchtouchmove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove'] }, + { name: 'catchtouchend', value: ['catchtouchend'] } ] catchEventList.forEach(event => { event.value.forEach(name => { if (props[name] && !eventHandlers[event.name]) { - eventHandlers[event.name] = (e: NativeSyntheticEvent) => { - e.stopPropagation() - } + eventHandlers[event.name] = noop } }) }) return eventHandlers } - const catchEventHandlers = injectCatchEvent(props) const layoutStyle = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {} + const innerProps = useInnerProps(props, extendObject({ + ref: nodeRef, + onLayout: onLayout, + style: [innerStyle, animatedStyles, layoutStyle] + }, injectCatchEvent(props))) + return createElement(GestureDetector, { gesture: gesture }, createElement( Animated.View, - extendObject({ - ref: nodeRef, - onLayout: onLayout, - style: [innerStyle, animatedStyles, layoutStyle] - }, catchEventHandlers), + innerProps, wrapChildren( props, { From 312f55e3d1f759b4f87205fd08f21d4ad36972a8 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 19 Dec 2024 20:43:41 +0800 Subject: [PATCH 07/20] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E8=A7=A6=E5=8F=91=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 4a1a37fe41..d9f4abc677 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -531,24 +531,23 @@ const _MovableView = forwardRef, MovableViewP } }) - const injectCatchEvent = (props: Record) => { - const eventHandlers: Record = {} - const catchEventList = [ - { name: 'bindtouchstart', value: ['bindtouchstart'] }, - { name: 'bindtouchmove', value: ['bindtouchmove', 'bindvtouchmove', 'bindhtouchmove'] }, - { name: 'bindtouchend', value: ['bindtouchend'] }, - { name: 'catchtouchstart', value: ['catchtouchstart'] }, - { name: 'catchtouchmove', value: ['catchtouchmove', 'catchvtouchmove', 'catchhtouchmove'] }, - { name: 'catchtouchend', value: ['catchtouchend'] } + const proxyTouchEvent = () => { + const handlers: Record = {} + + const events = [ + { type: 'touchstart' }, + { type: 'touchmove', alias: ['vtouchmove', 'htouchmove'] }, + { type: 'touchend' } ] - catchEventList.forEach(event => { - event.value.forEach(name => { - if (props[name] && !eventHandlers[event.name]) { - eventHandlers[event.name] = noop - } - }) + + events.forEach(({ type, alias = [] }) => { + const hasEvent = (prefix: string) => props[prefix + type as keyof MovableViewProps] || alias.some(name => props[prefix + name as keyof MovableViewProps]) + + if (hasEvent('bind')) handlers[`bind${type}`] = noop + if (hasEvent('catch')) handlers[`catch${type}`] = noop }) - return eventHandlers + + return handlers } const layoutStyle = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {} @@ -557,7 +556,7 @@ const _MovableView = forwardRef, MovableViewP ref: nodeRef, onLayout: onLayout, style: [innerStyle, animatedStyles, layoutStyle] - }, injectCatchEvent(props))) + }, proxyTouchEvent())) return createElement(GestureDetector, { gesture: gesture }, createElement( Animated.View, From b8218b3d81642ba680447f02f18c0b8b3f215ec4 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 19 Dec 2024 21:11:15 +0800 Subject: [PATCH 08/20] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E8=A7=A6=E5=8F=91=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-movable-view.tsx | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index d9f4abc677..859cd0ff62 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -22,7 +22,7 @@ import { StyleSheet, NativeSyntheticEvent, View, LayoutChangeEvent } from 'react import useInnerProps, { getCustomEvent } from './getInnerListeners' import useNodesRef, { HandlerRef } from './useNodesRef' import { MovableAreaContext } from './context' -import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, GestureHandler, flatGesture, extendObject } from './utils' +import { useTransformStyle, splitProps, splitStyle, HIDDEN_STYLE, wrapChildren, GestureHandler, flatGesture, extendObject, omit } from './utils' import { GestureDetector, Gesture, GestureTouchEvent, GestureStateChangeEvent, PanGestureHandlerEventPayload, PanGesture } from 'react-native-gesture-handler' import Animated, { useSharedValue, @@ -531,7 +531,7 @@ const _MovableView = forwardRef, MovableViewP } }) - const proxyTouchEvent = () => { + const rewriteCatchEvent = () => { const handlers: Record = {} const events = [ @@ -539,12 +539,11 @@ const _MovableView = forwardRef, MovableViewP { type: 'touchmove', alias: ['vtouchmove', 'htouchmove'] }, { type: 'touchend' } ] - events.forEach(({ type, alias = [] }) => { - const hasEvent = (prefix: string) => props[prefix + type as keyof MovableViewProps] || alias.some(name => props[prefix + name as keyof MovableViewProps]) - - if (hasEvent('bind')) handlers[`bind${type}`] = noop - if (hasEvent('catch')) handlers[`catch${type}`] = noop + const hasCatchEvent = + props[`catch${type}` as keyof typeof props] || + alias.some(name => props[`catch${name}` as keyof typeof props]) + if (hasCatchEvent) handlers[`catch${type}`] = noop }) return handlers @@ -552,11 +551,21 @@ const _MovableView = forwardRef, MovableViewP const layoutStyle = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {} - const innerProps = useInnerProps(props, extendObject({ + // bind 相关 touch 事件直接由 gesture 触发,无须重复挂载 + // catch 相关 touch 事件需要重写并通过 useInnerProps 注入阻止冒泡逻辑 + const filterProps = omit(props, [ + 'bindtouchstart', + 'bindtouchmove', + 'bindvtouchmove', + 'bindhtouchmove', + 'bindtouchend' + ]) + + const innerProps = useInnerProps(filterProps, extendObject({ ref: nodeRef, onLayout: onLayout, style: [innerStyle, animatedStyles, layoutStyle] - }, proxyTouchEvent())) + }, rewriteCatchEvent())) return createElement(GestureDetector, { gesture: gesture }, createElement( Animated.View, From ee58acd02b5cc7effc88b0f7eb38327c71a6cee1 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 19 Dec 2024 21:41:00 +0800 Subject: [PATCH 09/20] chore: del code --- .../lib/runtime/components/react/mpx-movable-view.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 859cd0ff62..1b6c976cf4 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -114,11 +114,7 @@ const _MovableView = forwardRef, MovableViewP catchvtouchmove, catchtouchmove, bindtouchend, - catchtouchend, - bindlongpress, - catchlongpress, - bindtap, - catchtap + catchtouchend } = props const { @@ -462,7 +458,7 @@ const _MovableView = forwardRef, MovableViewP 'worklet' isFirstTouch.value = true isMoving.value = false - if (bindtouchend || catchtouchend || bindtap || catchtap) { + if (bindtouchend || catchtouchend) { runOnJS(triggerEndOnJS)({ e }) } if (disabled) return From 40386b8eb93835baf8aeee409498ac816392d105 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Tue, 24 Dec 2024 14:36:04 +0800 Subject: [PATCH 10/20] =?UTF-8?q?chore:=20=E8=BF=87=E6=BB=A4catch=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/mpx-movable-view.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx index 1b6c976cf4..b6410e9034 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-movable-view.tsx @@ -554,7 +554,12 @@ const _MovableView = forwardRef, MovableViewP 'bindtouchmove', 'bindvtouchmove', 'bindhtouchmove', - 'bindtouchend' + 'bindtouchend', + 'catchtouchstart', + 'catchtouchmove', + 'catchvtouchmove', + 'catchhtouchmove', + 'catchtouchend' ]) const innerProps = useInnerProps(filterProps, extendObject({ From b7abd2b10542d6df3d8c2d11fc97db11ac597c93 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Thu, 2 Jan 2025 20:10:50 +0800 Subject: [PATCH 11/20] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3clientX=E3=80=81?= =?UTF-8?q?clientY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/getInnerListeners.ts | 18 ++++++++++-------- .../react/types/getInnerListeners.ts | 2 ++ .../runtime/components/react/types/global.d.ts | 6 ++++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 10f0ae1301..7ab88af149 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -1,5 +1,5 @@ import { useRef, useMemo, RefObject } from 'react' -import { hasOwn, collectDataset } from '@mpxjs/utils' +import { hasOwn, collectDataset, getFocusedNavigation } from '@mpxjs/utils' import { omit, extendObject } from './utils' import eventConfigMap from './event.config' import { @@ -19,6 +19,8 @@ const getTouchEvent = ( props: Props, config: UseInnerPropsConfig ) => { + const navigation = getFocusedNavigation() + const { y: navigationY = 0 } = navigation?.layout || {} const nativeEvent = event.nativeEvent const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent const { id } = props @@ -49,24 +51,24 @@ const getTouchEvent = ( target, detail: { x: pageX, - y: pageY + y: pageY - navigationY }, touches: touches.map((item) => { return { identifier: item.identifier, pageX: item.pageX, - pageY: item.pageY, - clientX: item.locationX, - clientY: item.locationY + pageY: item.pageY - navigationY, + clientX: nativeEvent.screenX, + clientY: nativeEvent.screenY - navigationY } }), changedTouches: changedTouches.map((item) => { return { identifier: item.identifier, pageX: item.pageX, - pageY: item.pageY, - clientX: item.locationX, - clientY: item.locationY + pageY: item.pageY - navigationY, + clientX: nativeEvent.screenX, + clientY: nativeEvent.screenY - navigationY } }), persist: event.persist, diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts index 78df219009..f097cc0260 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts @@ -14,6 +14,8 @@ type RemoveProps = string[]; type NativeTouchEvent = NativeSyntheticEvent interface NativeEvent { + screenY: any + screenX: any timestamp: number; pageX: number; pageY: number; diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts index 052fc1ac56..342059df0e 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts @@ -20,6 +20,12 @@ declare module '@mpxjs/utils' { left: number right: number }, + layout: { + x: number + y: number + width: number + height: number + }, setOptions: (params: Record) => void } | undefined } From 677ed7180ba94fe04faa83e602e73bb19c2058ed Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Fri, 3 Jan 2025 13:09:04 +0800 Subject: [PATCH 12/20] =?UTF-8?q?fix:=20longpress=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E8=AF=AF=E8=A7=A6=E5=8F=91=E5=A4=96=E5=B1=82tap=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/getInnerListeners.ts | 23 +++++++++++-------- .../react/types/getInnerListeners.ts | 4 ---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 7ab88af149..e1dd395e20 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -13,6 +13,10 @@ import { NativeTouchEvent } from './types/getInnerListeners' +const globalEventState = { + needPress: true +} + const getTouchEvent = ( type: string, event: NativeTouchEvent, @@ -113,7 +117,11 @@ function handleEmitEvent ( if (propsRef.current[event]) { const match = /^(catch|capture-catch):?(.*?)(?:\.(.*))?$/.exec(event) if (match) { - oe.stopPropagation() + const eventType = match[2] + if ((eventType === 'tap' && type === 'tap') || + (eventType.startsWith('touch') && type === eventType)) { + oe.stopPropagation() + } } propsRef.current[event]( getTouchEvent(type, oe, propsRef.current, config) @@ -131,7 +139,7 @@ function checkIsNeedPress (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: Math.abs(currentPageX - tapDetailInfo.x) > 1 || Math.abs(currentPageY - tapDetailInfo.y) > 1 ) { - ref.current!.needPress[type] = false + globalEventState.needPress = false ref.current!.startTimer[type] && clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null @@ -151,7 +159,7 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: 'capture-bindlongpress' ] ref.current!.startTimer[type] = null - ref.current!.needPress[type] = true + globalEventState.needPress = true const nativeEvent = e.nativeEvent ref.current!.mpxPressInfo.detail = { x: nativeEvent.changedTouches[0].pageX, @@ -175,7 +183,8 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: captureBindlongpress ) { ref.current!.startTimer[type] = setTimeout(() => { - ref.current!.needPress[type] = false + // 只要触发过longpress, 全局就不再触发tap + globalEventState.needPress = false handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config) }, 350) } @@ -211,7 +220,7 @@ function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: R clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config) - if (ref.current!.needPress[type]) { + if (globalEventState.needPress) { if (type === 'bubble' && config.disableTap) { return } @@ -275,10 +284,6 @@ const useInnerProps = ( bubble: null, capture: null }, - needPress: { - bubble: false, - capture: false - }, mpxPressInfo: { detail: { x: 0, diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts index f097cc0260..5d1d767c42 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts @@ -38,10 +38,6 @@ interface InnerRef { bubble: null | ReturnType; capture: null | ReturnType; }; - needPress: { - bubble: boolean; - capture: boolean; - }; mpxPressInfo: { detail: { x: number; From 860ba6261ef901cf448bd5713f6eec96b92427fb Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Fri, 3 Jan 2025 13:19:56 +0800 Subject: [PATCH 13/20] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/getInnerListeners.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index e1dd395e20..24a4305928 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -117,11 +117,7 @@ function handleEmitEvent ( if (propsRef.current[event]) { const match = /^(catch|capture-catch):?(.*?)(?:\.(.*))?$/.exec(event) if (match) { - const eventType = match[2] - if ((eventType === 'tap' && type === 'tap') || - (eventType.startsWith('touch') && type === eventType)) { - oe.stopPropagation() - } + oe.stopPropagation() } propsRef.current[event]( getTouchEvent(type, oe, propsRef.current, config) From 1bfeb6d83cfaaa69dc8f500e14a0571dae990e75 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Fri, 3 Jan 2025 14:59:10 +0800 Subject: [PATCH 14/20] =?UTF-8?q?chore:=20=E4=BC=98=E5=8C=96getFocusedNavi?= =?UTF-8?q?gation=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/getInnerListeners.ts | 61 +++++++++++-------- .../react/types/getInnerListeners.ts | 9 ++- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 24a4305928..7c75b9dea0 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -1,4 +1,4 @@ -import { useRef, useMemo, RefObject } from 'react' +import { useRef, useMemo, RefObject, useEffect } from 'react' import { hasOwn, collectDataset, getFocusedNavigation } from '@mpxjs/utils' import { omit, extendObject } from './utils' import eventConfigMap from './event.config' @@ -10,7 +10,8 @@ import { InnerRef, SetTimeoutReturnType, LayoutRef, - NativeTouchEvent + NativeTouchEvent, + NavigationLayout } from './types/getInnerListeners' const globalEventState = { @@ -21,10 +22,10 @@ const getTouchEvent = ( type: string, event: NativeTouchEvent, props: Props, - config: UseInnerPropsConfig + config: UseInnerPropsConfig, + navigationLayout: NavigationLayout ) => { - const navigation = getFocusedNavigation() - const { y: navigationY = 0 } = navigation?.layout || {} + const { y: navigationY = 0 } = navigationLayout.current const nativeEvent = event.nativeEvent const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent const { id } = props @@ -62,8 +63,8 @@ const getTouchEvent = ( identifier: item.identifier, pageX: item.pageX, pageY: item.pageY - navigationY, - clientX: nativeEvent.screenX, - clientY: nativeEvent.screenY - navigationY + clientX: item.pageX, + clientY: item.pageY - navigationY } }), changedTouches: changedTouches.map((item) => { @@ -71,8 +72,8 @@ const getTouchEvent = ( identifier: item.identifier, pageX: item.pageX, pageY: item.pageY - navigationY, - clientX: nativeEvent.screenX, - clientY: nativeEvent.screenY - navigationY + clientX: item.pageX, + clientY: item.pageY - navigationY } }), persist: event.persist, @@ -111,7 +112,8 @@ function handleEmitEvent ( type: string, oe: NativeTouchEvent, propsRef: Record, - config: UseInnerPropsConfig + config: UseInnerPropsConfig, + navigationLayout: NavigationLayout ) { events.forEach((event) => { if (propsRef.current[event]) { @@ -120,7 +122,7 @@ function handleEmitEvent ( oe.stopPropagation() } propsRef.current[event]( - getTouchEvent(type, oe, propsRef.current, config) + getTouchEvent(type, oe, propsRef.current, config, navigationLayout) ) } }) @@ -142,7 +144,7 @@ function checkIsNeedPress (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: } } -function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig) { +function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { e.persist() const bubbleTouchEvent = ['catchtouchstart', 'bindtouchstart'] const bubblePressEvent = ['catchlongpress', 'bindlongpress'] @@ -165,7 +167,7 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: type === 'bubble' ? bubbleTouchEvent : captureTouchEvent const currentPressEvent = type === 'bubble' ? bubblePressEvent : capturePressEvent - handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config) + handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config, navigationLayout) const { catchlongpress, bindlongpress, @@ -181,12 +183,12 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: ref.current!.startTimer[type] = setTimeout(() => { // 只要触发过longpress, 全局就不再触发tap globalEventState.needPress = false - handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config) + handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config, navigationLayout) }, 350) } } -function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig) { +function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { const bubbleTouchEvent = ['catchtouchmove', 'bindtouchmove'] const captureTouchEvent = [ 'capture-catchtouchmove', @@ -194,11 +196,11 @@ function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: ] const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent - handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config) + handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config, navigationLayout) checkIsNeedPress(e, type, ref) } -function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig) { +function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { // move event may not be triggered checkIsNeedPress(e, type, ref) const bubbleTouchEvent = ['catchtouchend', 'bindtouchend'] @@ -215,19 +217,22 @@ function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: R ref.current!.startTimer[type] && clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null - handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config) + handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config, navigationLayout) if (globalEventState.needPress) { if (type === 'bubble' && config.disableTap) { return } - handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config) + handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config, navigationLayout) } } function handleTouchcancel ( e: NativeTouchEvent, type: 'bubble' | 'capture', - ref: RefObject, propsRef: Record, config: UseInnerPropsConfig + ref: RefObject, + propsRef: Record, + config: UseInnerPropsConfig, + navigationLayout: NavigationLayout ) { const bubbleTouchEvent = ['catchtouchcancel', 'bindtouchcancel'] const captureTouchEvent = [ @@ -239,11 +244,11 @@ function handleTouchcancel ( ref.current!.startTimer[type] && clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null - handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config) + handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config, navigationLayout) } function createTouchEventHandler (eventName: 'onTouchStart'|'onTouchMove'|'onTouchEnd'|'onTouchCancel', type: 'bubble' | 'capture') { - return (e: NativeTouchEvent, ref: RefObject, propsRef: Record, config: UseInnerPropsConfig) => { + return (e: NativeTouchEvent, ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) => { const handlerMap = { onTouchStart: handleTouchstart, onTouchMove: handleTouchmove, @@ -253,7 +258,7 @@ function createTouchEventHandler (eventName: 'onTouchStart'|'onTouchMove'|'onTou const handler = handlerMap[eventName] if (handler) { - handler(e, type, ref, propsRef, config) + handler(e, type, ref, propsRef, config, navigationLayout) } } } @@ -294,6 +299,8 @@ const useInnerProps = ( layoutRef: { current: {} }, disableTap: false } + const navigationLayout = useRef({ x: 0, y: 0, width: 0, height: 0 }) + const removeProps = [ 'children', 'enable-background', @@ -319,6 +326,12 @@ const useInnerProps = ( } } + useEffect(() => { + setTimeout(() => { + navigationLayout.current = getFocusedNavigation()?.layout || { x: 0, y: 0, width: 0, height: 0 } + }) + }, []) + const events = useMemo(() => { if (!rawEventKeys.length) { return {} @@ -335,7 +348,7 @@ const useInnerProps = ( touchEventList.forEach((item) => { if (finalEventKeys.includes(item.eventName)) { events[item.eventName] = (e: NativeTouchEvent) => - item.handler(e, ref, propsRef, config) + item.handler(e, ref, propsRef, config, navigationLayout) } }) diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts index 5d1d767c42..f293714327 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts @@ -13,6 +13,12 @@ type RemoveProps = string[]; type NativeTouchEvent = NativeSyntheticEvent +type NavigationLayout = MutableRefObject<{ + x: number; + y: number; + width: number; + height: number; +}> interface NativeEvent { screenY: any screenX: any @@ -63,5 +69,6 @@ export { InnerRef, LayoutRef, SetTimeoutReturnType, - DataSetType + DataSetType, + NavigationLayout } From d02e08109062c10966d018b15097d8f445c4f3a5 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Fri, 3 Jan 2025 15:04:24 +0800 Subject: [PATCH 15/20] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8ts=E7=B1=BB=E5=9E=8B=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/runtime/components/react/types/getInnerListeners.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts index f293714327..f774446871 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts @@ -20,8 +20,6 @@ type NavigationLayout = MutableRefObject<{ height: number; }> interface NativeEvent { - screenY: any - screenX: any timestamp: number; pageX: number; pageY: number; From d9e7dca5783910813ad8a6ed61a5b63b381820f3 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Fri, 3 Jan 2025 17:17:51 +0800 Subject: [PATCH 16/20] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9Navigation?= =?UTF-8?q?=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/getInnerListeners.ts | 47 +++++++++---------- .../react/types/getInnerListeners.ts | 9 +--- .../components/react/types/global.d.ts | 4 ++ 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 7c75b9dea0..33c0fac145 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -1,5 +1,6 @@ import { useRef, useMemo, RefObject, useEffect } from 'react' -import { hasOwn, collectDataset, getFocusedNavigation } from '@mpxjs/utils' +import { hasOwn, collectDataset } from '@mpxjs/utils' +import { useNavigation } from '@react-navigation/native' import { omit, extendObject } from './utils' import eventConfigMap from './event.config' import { @@ -11,7 +12,7 @@ import { SetTimeoutReturnType, LayoutRef, NativeTouchEvent, - NavigationLayout + Navigation } from './types/getInnerListeners' const globalEventState = { @@ -23,9 +24,9 @@ const getTouchEvent = ( event: NativeTouchEvent, props: Props, config: UseInnerPropsConfig, - navigationLayout: NavigationLayout + navigation: Navigation ) => { - const { y: navigationY = 0 } = navigationLayout.current + const { y: navigationY = 0 } = navigation?.layout || {} const nativeEvent = event.nativeEvent const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent const { id } = props @@ -113,7 +114,7 @@ function handleEmitEvent ( oe: NativeTouchEvent, propsRef: Record, config: UseInnerPropsConfig, - navigationLayout: NavigationLayout + navigation: Navigation ) { events.forEach((event) => { if (propsRef.current[event]) { @@ -122,7 +123,7 @@ function handleEmitEvent ( oe.stopPropagation() } propsRef.current[event]( - getTouchEvent(type, oe, propsRef.current, config, navigationLayout) + getTouchEvent(type, oe, propsRef.current, config, navigation) ) } }) @@ -144,7 +145,7 @@ function checkIsNeedPress (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: } } -function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { +function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigation: Navigation) { e.persist() const bubbleTouchEvent = ['catchtouchstart', 'bindtouchstart'] const bubblePressEvent = ['catchlongpress', 'bindlongpress'] @@ -167,7 +168,7 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: type === 'bubble' ? bubbleTouchEvent : captureTouchEvent const currentPressEvent = type === 'bubble' ? bubblePressEvent : capturePressEvent - handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config, navigationLayout) + handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config, navigation) const { catchlongpress, bindlongpress, @@ -183,12 +184,12 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: ref.current!.startTimer[type] = setTimeout(() => { // 只要触发过longpress, 全局就不再触发tap globalEventState.needPress = false - handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config, navigationLayout) + handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config, navigation) }, 350) } } -function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { +function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigation: Navigation) { const bubbleTouchEvent = ['catchtouchmove', 'bindtouchmove'] const captureTouchEvent = [ 'capture-catchtouchmove', @@ -196,11 +197,11 @@ function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: ] const currentTouchEvent = type === 'bubble' ? bubbleTouchEvent : captureTouchEvent - handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config, navigationLayout) + handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config, navigation) checkIsNeedPress(e, type, ref) } -function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) { +function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigation: Navigation) { // move event may not be triggered checkIsNeedPress(e, type, ref) const bubbleTouchEvent = ['catchtouchend', 'bindtouchend'] @@ -217,12 +218,12 @@ function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: R ref.current!.startTimer[type] && clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null - handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config, navigationLayout) + handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config, navigation) if (globalEventState.needPress) { if (type === 'bubble' && config.disableTap) { return } - handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config, navigationLayout) + handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config, navigation) } } @@ -232,7 +233,7 @@ function handleTouchcancel ( ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, - navigationLayout: NavigationLayout + navigation: Navigation ) { const bubbleTouchEvent = ['catchtouchcancel', 'bindtouchcancel'] const captureTouchEvent = [ @@ -244,11 +245,11 @@ function handleTouchcancel ( ref.current!.startTimer[type] && clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType) ref.current!.startTimer[type] = null - handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config, navigationLayout) + handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config, navigation) } function createTouchEventHandler (eventName: 'onTouchStart'|'onTouchMove'|'onTouchEnd'|'onTouchCancel', type: 'bubble' | 'capture') { - return (e: NativeTouchEvent, ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigationLayout: NavigationLayout) => { + return (e: NativeTouchEvent, ref: RefObject, propsRef: Record, config: UseInnerPropsConfig, navigation: Navigation) => { const handlerMap = { onTouchStart: handleTouchstart, onTouchMove: handleTouchmove, @@ -258,7 +259,7 @@ function createTouchEventHandler (eventName: 'onTouchStart'|'onTouchMove'|'onTou const handler = handlerMap[eventName] if (handler) { - handler(e, type, ref, propsRef, config, navigationLayout) + handler(e, type, ref, propsRef, config, navigation) } } } @@ -299,7 +300,7 @@ const useInnerProps = ( layoutRef: { current: {} }, disableTap: false } - const navigationLayout = useRef({ x: 0, y: 0, width: 0, height: 0 }) + const navigation = useNavigation() const removeProps = [ 'children', @@ -326,12 +327,6 @@ const useInnerProps = ( } } - useEffect(() => { - setTimeout(() => { - navigationLayout.current = getFocusedNavigation()?.layout || { x: 0, y: 0, width: 0, height: 0 } - }) - }, []) - const events = useMemo(() => { if (!rawEventKeys.length) { return {} @@ -348,7 +343,7 @@ const useInnerProps = ( touchEventList.forEach((item) => { if (finalEventKeys.includes(item.eventName)) { events[item.eventName] = (e: NativeTouchEvent) => - item.handler(e, ref, propsRef, config, navigationLayout) + item.handler(e, ref, propsRef, config, navigation) } }) diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts index f774446871..e5463c7275 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts @@ -13,12 +13,7 @@ type RemoveProps = string[]; type NativeTouchEvent = NativeSyntheticEvent -type NavigationLayout = MutableRefObject<{ - x: number; - y: number; - width: number; - height: number; -}> +type Navigation = Record interface NativeEvent { timestamp: number; pageX: number; @@ -68,5 +63,5 @@ export { LayoutRef, SetTimeoutReturnType, DataSetType, - NavigationLayout + Navigation } diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts index 342059df0e..68e417603a 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts @@ -33,3 +33,7 @@ declare module '@mpxjs/utils' { declare let global: { __formatValue (value: string): string | number } & Record + +declare module '@react-navigation/native' { + export function useNavigation (): any +} From ae9db31cbebb258b2ca8c5cb7b14ba99c7f3afa4 Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Fri, 3 Jan 2025 18:02:47 +0800 Subject: [PATCH 17/20] adjust navigation in hooks --- .../components/react/getInnerListeners.ts | 2 +- .../runtime/components/react/types/common.ts | 20 ------ .../react/types/getInnerListeners.ts | 67 ------------------- .../components/react/types/global.d.ts | 2 +- .../lib/runtime/components/react/utils.tsx | 15 +++-- 5 files changed, 10 insertions(+), 96 deletions(-) delete mode 100644 packages/webpack-plugin/lib/runtime/components/react/types/common.ts delete mode 100644 packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts diff --git a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts index 6efc95e989..6d00a5ceba 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/getInnerListeners.ts @@ -1,4 +1,4 @@ -import { useRef, useMemo, RefObject, useEffect } from 'react' +import { useRef, useMemo, RefObject } from 'react' import { hasOwn, collectDataset } from '@mpxjs/utils' import { useNavigation } from '@react-navigation/native' import { omit, extendObject } from './utils' diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/common.ts b/packages/webpack-plugin/lib/runtime/components/react/types/common.ts deleted file mode 100644 index 716e3616c5..0000000000 --- a/packages/webpack-plugin/lib/runtime/components/react/types/common.ts +++ /dev/null @@ -1,20 +0,0 @@ -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 - 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 diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts deleted file mode 100644 index e5463c7275..0000000000 --- a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { MutableRefObject } from 'react' -import { NativeSyntheticEvent } from 'react-native' - -type LayoutRef = MutableRefObject - -type SetTimeoutReturnType = ReturnType - -type Props = Record - -type AdditionalProps = Record; - -type RemoveProps = string[]; - -type NativeTouchEvent = NativeSyntheticEvent - -type Navigation = Record -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; - capture: null | ReturnType; - }; - 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 -} diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts index 68e417603a..82d5a57476 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/types/global.d.ts @@ -35,5 +35,5 @@ declare let global: { } & Record declare module '@react-navigation/native' { - export function useNavigation (): any + export function useNavigation (): Record } diff --git a/packages/webpack-plugin/lib/runtime/components/react/utils.tsx b/packages/webpack-plugin/lib/runtime/components/react/utils.tsx index 5c933aea4f..08fac95572 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/utils.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/utils.tsx @@ -1,9 +1,10 @@ import { useEffect, useCallback, useMemo, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react' import { LayoutChangeEvent, TextStyle, ImageProps, Image } from 'react-native' -import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils' +import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils' import { VarContext } from './context' import { ExpressionParser, parseFunc, ReplaceSource } from './parser' import { initialWindowMetrics } from 'react-native-safe-area-context' +import { useNavigation } from '@react-navigation/native' import FastImage, { FastImageProps } from '@d11/react-native-fast-image' import type { AnyFunc, ExtendedFunctionComponent } from './types/common' @@ -32,8 +33,7 @@ const safeAreaInsetMap: Record = { 'safe-area-inset-left': 'left' } -function getSafeAreaInset (name: string) { - const navigation = getFocusedNavigation() +function getSafeAreaInset (name: string, navigation: Record) { const insets = extendObject({}, initialWindowMetrics?.insets, navigation?.insets) return insets[safeAreaInsetMap[name]] } @@ -232,7 +232,7 @@ function transformVar (styleObj: Record, varKeyPaths: Array, envKeyPaths: Array>) { +function transformEnv (styleObj: Record, envKeyPaths: Array>, navigation: Record) { envKeyPaths.forEach((envKeyPath) => { setStyle(styleObj, envKeyPath, ({ target, key, value }) => { const parsed = parseFunc(value, 'env') @@ -240,7 +240,7 @@ function transformEnv (styleObj: Record, envKeyPaths: Array { const name = args[0] const fallback = args[1] || '' - const value = '' + (getSafeAreaInset(name) ?? global.__formatValue(fallback)) + const value = '' + (getSafeAreaInset(name, navigation) ?? global.__formatValue(fallback)) replaced.replace(start, end - 1, value) }) target[key] = global.__formatValue(replaced.source()) @@ -302,6 +302,7 @@ export function useTransformStyle (styleObj: Record = {}, { enableV const envKeyPaths: Array> = [] const [width, setWidth] = useState(0) const [height, setHeight] = useState(0) + const navigation = useNavigation() function varVisitor ({ key, value, keyPath }: VisitorArg) { if (keyPath.length === 1) { @@ -396,7 +397,7 @@ export function useTransformStyle (styleObj: Record = {}, { enableV } // apply env - transformEnv(normalStyle, envKeyPaths) + transformEnv(normalStyle, envKeyPaths, navigation) // apply percent transformPercent(normalStyle, percentKeyPaths, percentConfig) // apply calc @@ -595,7 +596,7 @@ export const useStableCallback = ( ) } -export const usePrevious = (value: T): T | undefined => { +export function usePrevious (value: T): T | undefined { const ref = useRef() const prev = ref.current ref.current = value From ec89f05648d2f9c192504d18bc2afc7543d1f78c Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Mon, 6 Jan 2025 12:59:03 +0800 Subject: [PATCH 18/20] add types --- .../components/react/types/common.d.ts | 20 ++++++ .../react/types/getInnerListeners.d.ts | 68 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 packages/webpack-plugin/lib/runtime/components/react/types/common.d.ts create mode 100644 packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.d.ts diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/common.d.ts b/packages/webpack-plugin/lib/runtime/components/react/types/common.d.ts new file mode 100644 index 0000000000..716e3616c5 --- /dev/null +++ b/packages/webpack-plugin/lib/runtime/components/react/types/common.d.ts @@ -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 + 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 diff --git a/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.d.ts b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.d.ts new file mode 100644 index 0000000000..317d483d62 --- /dev/null +++ b/packages/webpack-plugin/lib/runtime/components/react/types/getInnerListeners.d.ts @@ -0,0 +1,68 @@ +import { MutableRefObject } from 'react' +import { NativeSyntheticEvent } from 'react-native' + +type LayoutRef = MutableRefObject + +type SetTimeoutReturnType = ReturnType + +type Props = Record + +type AdditionalProps = Record; + +type RemoveProps = string[]; + +type NativeTouchEvent = NativeSyntheticEvent + +type Navigation = Record + +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; + capture: null | ReturnType; + }; + 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 +} From b8dee70155ab4ff34976e6cc09f546fd6031c223 Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Wed, 8 Jan 2025 16:48:00 +0800 Subject: [PATCH 19/20] support hot launch in rn --- .../src/platform/api/system/index.web.js | 2 +- .../src/platform/api/system/rnSystem.js | 11 +--- packages/core/src/platform/createApp.ios.js | 59 ++++++++----------- packages/core/src/platform/createApp.js | 47 +++++++-------- packages/core/src/platform/export/inject.js | 5 +- .../platform/patch/getDefaultOptions.ios.js | 6 +- 6 files changed, 51 insertions(+), 79 deletions(-) diff --git a/packages/api-proxy/src/platform/api/system/index.web.js b/packages/api-proxy/src/platform/api/system/index.web.js index 2614aa2562..0e756b73d9 100644 --- a/packages/api-proxy/src/platform/api/system/index.web.js +++ b/packages/api-proxy/src/platform/api/system/index.web.js @@ -139,7 +139,7 @@ const getLaunchOptionsSync = function () { throwSSRWarning('getLaunchOptionsSync API is running in non browser environments') return } - return global.__mpxEnterOptions || {} + return global.__mpxLaunchOptions || {} } export { diff --git a/packages/api-proxy/src/platform/api/system/rnSystem.js b/packages/api-proxy/src/platform/api/system/rnSystem.js index acf3965ed9..abc0501466 100644 --- a/packages/api-proxy/src/platform/api/system/rnSystem.js +++ b/packages/api-proxy/src/platform/api/system/rnSystem.js @@ -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 { diff --git a/packages/core/src/platform/createApp.ios.js b/packages/core/src/platform/createApp.ios.js index b3ef722394..64123508ec 100644 --- a/packages/core/src/platform/createApp.ios.js +++ b/packages/core/src/platform/createApp.ios.js @@ -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) @@ -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() @@ -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 @@ -177,6 +166,8 @@ export default function createApp (option, config = {}) { return () => { changeSubscription && changeSubscription.remove() resizeSubScription && resizeSubScription.remove() + // 热启动情况下,app会被销毁重建,将__mpxAppHotLaunched重置保障路由等初始化逻辑正确执行 + global.__mpxAppHotLaunched = false } }, []) diff --git a/packages/core/src/platform/createApp.js b/packages/core/src/platform/createApp.js index 0f35cf97e5..e953d40b86 100644 --- a/packages/core/src/platform/createApp.js +++ b/packages/core/src/platform/createApp.js @@ -24,19 +24,19 @@ 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) - Object.assign(this, appData) const current = this.$root.$options?.router?.currentRoute || {} const options = { path: current.path && current.path.replace(/^\//, ''), @@ -45,48 +45,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) diff --git a/packages/core/src/platform/export/inject.js b/packages/core/src/platform/export/inject.js index ea73092074..bc387994d0 100644 --- a/packages/core/src/platform/export/inject.js +++ b/packages/core/src/platform/export/inject.js @@ -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 diff --git a/packages/core/src/platform/patch/getDefaultOptions.ios.js b/packages/core/src/platform/patch/getDefaultOptions.ios.js index ac4c5c7561..0189823b53 100644 --- a/packages/core/src/platform/patch/getDefaultOptions.ios.js +++ b/packages/core/src/platform/patch/getDefaultOptions.ios.js @@ -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]) @@ -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 || {}]) From 53b8e0850298f5f5e7b69d69785eca2196743a78 Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Wed, 8 Jan 2025 17:16:19 +0800 Subject: [PATCH 20/20] fix web app provide --- packages/core/src/platform/createApp.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/core/src/platform/createApp.js b/packages/core/src/platform/createApp.js index e953d40b86..f3e847cb61 100644 --- a/packages/core/src/platform/createApp.js +++ b/packages/core/src/platform/createApp.js @@ -36,6 +36,10 @@ export default function createApp (options, config = {}) { }] if (__mpx_mode__ === 'web') { builtInMixins.push({ + beforeCreate () { + // for vue provide vm access + Object.assign(this, appData) + }, created () { const current = this.$root.$options?.router?.currentRoute || {} const options = {