react-native-tvos icon indicating copy to clipboard operation
react-native-tvos copied to clipboard

TVFocusGuideView not taking the proper focus destination after first load

Open ramiro-r opened this issue 3 years ago • 6 comments

Hi folks! We're facing a weird issue with the TvFocusGuide destinations, not sure if we're doing something in a wrong way here, any help would be much appreciated. I'm sorry if this is not the right category to post it feel free to point that out.

We currently have a Carousel component wrapped in a block component that contains a TvFocusGuide instance. We would like to always focus the first Carousel Item every time the entire Carousel gets navigated to by the user using the remote. Unfortunately, that doesn't seem to work after the first load sometimes, besides we're seeing the ref being populated correctly. After the user gets to the carousel for the first time then it starts working fine when you get out and back to the carousel.

React Native version:

[email protected]

Snack, code example, screenshot, or link to a repository:

This is our current structure:

// MyBlock wrapper component. 
// The AnimatedBlock it's a styled View that adds an opacity animation when the block is on viewport 
// and some parametrized paddings

<AnimatedBlock
      ...
      style={{ opacity: opacity }}
      marginVertical={props.marginVertical ?? platformConfig.marginVertical}
      paddingHorizontal={props.paddingHorizontal ?? platformConfig.paddingHorizontal}
      flexGrow={props.flexGrow}>
      <TVFocusGuideView destinations={props.destinations || []}>
        <View style={{ flexGrow: Number(props.flexGrow), overflow: props.overflow || Overflow.Visible }} ref={blockRef}>
          {props.children}
        </View>
      </TVFocusGuideView>
</AnimatedBlock>

//Carousel component
const focusOnTvRef = useRef<TouchableHighlight>(null);

<MyBlock destinations={focusOnTvRef?.current ? [focusOnTvRef.current] : []}>
  <Flatlist 
     ...
     data={items}
     renderItem={renderItem}
  />
</MyBlock>

// renderItem. We're setting the ref only on the first item
...

return <CarouselImage ref={index === 0 ? focusOnTvRef : undefined} ... />;

//CarouselImage component
const CarouselImage: React.FC<CarouselImageProps> = (
  props: CarouselImageProps,
  ref?: RefObject<TouchableHighlight>,
): JSX.Element => {
return (
    <Hoverable onHover={setIsHovered}>
      <Animated.View style={[{ marginBottom: containerHeightOffsetAnimated }]}>
        <CarouselImageWrapper width={props.width} paddingHorizontal={props.paddingHorizontal}>
          <FocusSizeAnimation active={isCardActive}>
            <TouchableHighlight ref={ref}>
              ...
            </TouchableHighlight>
          </FocusSizeAnimation>
        </CarouselImageWrapper>
      </Animated.View>
    </Hoverable>
);

export default observer(CarouselImage, { forwardRef: true }); // we're using mobx, forwarding the parent ref

ramiro-r avatar Jul 27 '21 14:07 ramiro-r

I suspect that the focus destination may not be actually rendered until the user moves focus to the carousel, at least in some cases.

Can you please try this with the latest release (0.64.2-2)? If it still reproduces, it would be great to have a complete working example that shows the issue.

douglowder avatar Aug 07 '21 18:08 douglowder

@ramiro-r I believe this might be fixed by https://github.com/react-native-tvos/react-native-tvos/pull/214 , which is merged in 0.64.2-4. Can you check?

douglowder avatar Sep 22 '21 20:09 douglowder

I am having the exact same issue as @ramiro-r. My project is using [email protected]

danychi avatar Sep 26 '22 14:09 danychi

@danychi if you have a working example that reproduces the issue, please provide it here and I'll take a look.

douglowder avatar Sep 26 '22 15:09 douglowder

Hi @douglowder, sorry for the late response, here it's the link to the repository where you can reproduce the bug.

tvOS On tvOS the TVFocusGuideView works only after you focus once on the Carousel https://user-images.githubusercontent.com/45874461/193811315-71afa4e2-a743-4275-a481-77556db36281.mov

Android TV It doesn't seem to work https://user-images.githubusercontent.com/45874461/193811637-b6310dd3-8b5e-4112-96b9-0c342481e7e6.mov

danychi avatar Oct 04 '22 11:10 danychi

Thanks @danychi I'm taking a look at the example app now and testing out some changes.

douglowder avatar Oct 04 '22 23:10 douglowder

this issue is still open in latest version, for some reason we need to change focus first and then it works.

sebasg0 avatar Dec 22 '22 15:12 sebasg0

has someone fixed this?

sebasg0 avatar Dec 22 '22 15:12 sebasg0

@sebasg0 I think you can fix this by setting the destinations with a delay of 1ms

const [setDestinations, destinations] = useState([]);

useEffect(() => {
  setTimeout(() => setDestinations(...), 1);
},[]);

...

return (
<TvFocusGuideView destinations={destinations}>
...
)

danychi avatar Dec 22 '22 20:12 danychi

Hey eveybody, here's the fix: https://github.com/react-native-tvos/react-native-tvos/pull/420

yusufyildirim avatar Dec 29 '22 12:12 yusufyildirim

Hello all I have same issue with Android TV. It works fine with tvOS but not focus to proper destination in android TV. I am using [email protected]. Please help Thanks in advance.

vishalhyperspace avatar Mar 27 '23 12:03 vishalhyperspace