Skip to content

Commit

Permalink
Merged PR 34536: Fix product tour location
Browse files Browse the repository at this point in the history
fix product tour location
  • Loading branch information
RikSchefferAmsterdam committed Oct 16, 2024
2 parents 19d2603 + 402a5ad commit 2e8145a
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 27 deletions.
32 changes: 17 additions & 15 deletions src/components/features/product-tour/ProductTourTipWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,23 @@ export const ProductTourTipWrapper = ({
useBlurEffect(handleHasSeenTip)

return (
<View>
{!hasSeenTip && !isScreenReaderEnabled && (
<Tooltip
accessibilityLabel={TipText[tipSlug]}
extraSpace={extraSpace}
fadeIn
onPress={handleHasSeenTip}
placement={placement}
productTourTipTargetLayout={productTourTipTargetLayout}
ref={setElementRef}
startFadeIn={isElementVisible ?? hasNoScrollViewParent}
testID={testID}
text={TipText[tipSlug]}
/>
)}
<View testID="ProductTourTipWrapper">
{!hasSeenTip &&
!isScreenReaderEnabled &&
!!productTourTipTargetLayout && (
<Tooltip
accessibilityLabel={TipText[tipSlug]}
extraSpace={extraSpace}
fadeIn
onPress={handleHasSeenTip}
placement={placement}
productTourTipTargetLayout={productTourTipTargetLayout}
ref={setElementRef}
startFadeIn={isElementVisible ?? hasNoScrollViewParent}
testID={testID}
text={TipText[tipSlug]}
/>
)}
<View
collapsable={false}
onLayout={measureTarget}
Expand Down
36 changes: 32 additions & 4 deletions src/components/features/product-tour/useMeasureTarget.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import {useIsFocused} from '@react-navigation/core'
import {useCallback, useEffect, useState} from 'react'
import {useCallback, useEffect, useRef, useState} from 'react'
import {LayoutRectangle, useWindowDimensions, View} from 'react-native'
import {measureElement} from '@/components/features/product-tour/utils'
import {useDeviceContext} from '@/hooks/useDeviceContext'

type TargetRef = React.RefObject<View | null>

export const useMeasureTarget = (targetRef: TargetRef) => {
const isFocused = useIsFocused()
const windowDimensions = useWindowDimensions()
const [layout, setLayout] = useState<LayoutRectangle>()
const oldLayout = useRef<LayoutRectangle>({
x: 0,
y: 0,
width: 0,
height: 0,
})

const measureTarget = useCallback(() => {
if (!isFocused) {
Expand All @@ -18,15 +25,36 @@ export const useMeasureTarget = (targetRef: TargetRef) => {
void measureElement(targetRef.current as unknown as View).then(
({x, y, width, height}) => {
if (x === 0 && y === 0 && width === 0 && height === 0) {
setTimeout(measureTarget, 500)
setTimeout(measureTarget, 300)

return
}

const layoutChanged =
oldLayout.current.height !== height ||
oldLayout.current.width !== width ||
oldLayout.current.x !== x ||
oldLayout.current.y !== y

if (layoutChanged) {
setTimeout(measureTarget, 300)
} else {
setLayout({x, y, width, height})
}

oldLayout.current = {x, y, width, height}
},
() => setTimeout(measureTarget, 200),
)
}, [isFocused, targetRef])
}, [isFocused, targetRef, oldLayout])

const {isPortrait} = useDeviceContext()

useEffect(measureTarget, [isFocused, measureTarget, windowDimensions])
useEffect(() => {
setLayout(undefined)
measureTarget()
setTimeout(measureTarget, 200)
}, [isPortrait, measureTarget, isFocused, windowDimensions])

return {layout, measureTarget}
}
12 changes: 8 additions & 4 deletions src/components/features/product-tour/utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import {LayoutRectangle, View} from 'react-native'

export const measureElement = (element: View) =>
new Promise<LayoutRectangle>(resolve => {
element.measureInWindow((x, y, width, height) => {
resolve({x, height, width, y})
})
new Promise<LayoutRectangle>((resolve, reject) => {
if (element) {
element.measureInWindow((x, y, width, height) => {
resolve({x, height, width, y})
})
} else {
reject(new Error('Element is not defined'))
}
})

export const computeIsElementVisible = (
Expand Down
14 changes: 10 additions & 4 deletions src/components/features/product-tour/withTrackScroll.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
ForwardedRef,
createContext,
forwardRef,
useCallback,
useEffect,
useMemo,
useRef,
useState,
Expand Down Expand Up @@ -43,7 +45,7 @@ const withTrackScroll = (
const [elementRef, setElementRef] = useState<View | null>(null)
const [isElementVisible, setIsElementVisible] = useState<boolean>(false)

const getIsElementVisibible = async () => {
const getIsElementVisible = useCallback(async () => {
if (!scrollViewRef?.current || !elementRef) {
return false
}
Expand All @@ -56,12 +58,12 @@ const withTrackScroll = (
setIsElementVisible(
computeIsElementVisible(scrollViewLayout, elementLayout),
)
}
}, [scrollViewRef, elementRef])

const scrollViewProps = {
...props,
onLayout: getIsElementVisibible,
onScroll: getIsElementVisibible,
onLayout: getIsElementVisible,
onScroll: getIsElementVisible,
[refPropName]: scrollViewRef,
scrollEventThrottle: 16,
}
Expand All @@ -71,6 +73,10 @@ const withTrackScroll = (
[isElementVisible, setElementRef],
)

useEffect(() => {
void getIsElementVisible()
}, [getIsElementVisible])

return (
<ScrollViewComp {...scrollViewProps}>
<ScrollContext.Provider value={value}>
Expand Down

0 comments on commit 2e8145a

Please sign in to comment.