Pan Responder enclosing a FlatList

Viewed 16

I have a snap carousel, that has a "Details Card" that can be pulled up with details for each of the items in the carousel. The details card updates as the carousel moves through the entries. This is all working well. The details card also has some comments, however, that are in a flat list. When I "pull up" on the details card, I am able to see everything and it moves to the top of the screen. When I try to scroll through comments, however, it just starts to close the details card.

I used this Restricting jQuery-ui Draggable to drag up only, within a given area to try to give me an idea of what I could do, so here is what that kind of looks like:

    const detCtx = useContext(DetContext);

    const pan = useRef(new Animated.ValueXY()).current;
    const [realPosition, setRealPosition] = useState(new Animated.ValueXY({ x: 0, y: 0 }));
    const { height: viewportHeight, width: viewportWidth } = useWindowDimensions();
    const [needToResetCardHeightVal, setNeedToResetCardHeightVal] = useState<boolean>(false);
    const [userImage, setUserImage] = useState(Images.sampleImage);
    const [expanded, setExpanded] = useState(false);

    useEffect(() => {
        if (detCtx.item) {
            const { user_profile_image_id } = detCtx.item || {};

            if (user_profile_image_id !== null) {
                let ui = { uri: mediaEndPoints.images.public(user_profile_image_id!) };
                setUserImage(ui);
            }
        }
    }, [detCtx.item]);

    useEffect(() => {
        if (needToResetCardHeightVal) {
            pan.setValue({
                x: realPosition.x._value,
                y: realPosition.y._value < -viewportHeight / 4 ? -viewportHeight / 2 + 20 : 0
            });

            setExpanded(realPosition.y._value < -viewportHeight / 4 ? true : false);
            pan.flattenOffset();
            setNeedToResetCardHeightVal(false);
        }
    }, [realPosition.y, needToResetCardHeightVal]);

    const panResponder = useRef(
        PanResponder.create({
            onMoveShouldSetPanResponder: (_, gestureState) => {
                const { dx, dy, moveY } = gestureState;

                return (
                    (dx > 2 || dx < -2 || dy > 2 || dy < -2) &&
                    !expanded &&
                    (moveY >= viewportHeight / 2 || moveY <= viewportHeight / 2 + 50)
                );
            },

            //onMoveShouldSetPanResponderCapture: (_, gestureState) => {
            //    return false;
            // const { dx, dy, moveY } = gestureState;
            // reactotron.log!("moveY", moveY, viewportHeight / 2, viewportHeight / 2 + 50);
            // return (
            //     (dx > 2 || dx < -2 || dy > 2 || dy < -2) &&
            //     (moveY >= viewportHeight / 2 || moveY <= viewportHeight / 2 + 50)
            // );
            //},
            //onPanResponderGrant: () => {},
            onPanResponderMove: (evt, gestureState) => {
                const { dx, dy, moveY } = gestureState;

                if (!expanded && moveY > viewportHeight / 2 + dy && moveY < viewportHeight / 2 + 50 + dy) {
                    if (dy < 0 && dy > -viewportHeight / 2) {
                        pan.setValue({ x: dx, y: dy });
                    } else if (expanded && pan.y._value <= 0 && dy > 0 && dy < viewportHeight / 2) {
                        pan.setValue({ x: 0, y: dy });
                    }
                }
            },
            onPanResponderRelease: (evt, gestureState) => {
                const { dx, dy } = gestureState;

                if (dy > 2 || dy < -2) {
                    setNeedToResetCardHeightVal(true);
                }
            }
        })
    ).current;

    pan.addListener(test => {
        if (test.y._value < 0 > -viewportHeight / 2) {
            setRealPosition(new Animated.ValueXY({ x: test.x, y: test.y }));
        }
    });

    return (
        <Animated.View
            style={{
                flex: 1,
                width: "100%",
                borderTopLeftRadius: 25,
                borderTopRightRadius: 25,
                position: "absolute",
                bottom: 0,
                top: viewportHeight / 2,
                zIndex: 1,
                height: "100%",
                backgroundColor: "white",
                transform: [
                    {
                        translateY: pan.y
                    }
                ]
            }}
            {...panResponder.panHandlers}
        >
            <View>
                <View style={{ height: 50, backgroundColor: "purple" }}></View>
                {detCtx.item && (
                    <View style={{ flexShrink: 1, height: "100%" }}>
                        <View style={{ flexShrink: 1 }}>
                            <UserInfo userId={detCtx.item?.user_id} />
                        </View>
                        <View style={{ flexShrink: 1 }}>
                            <Progress />
                        </View>
                        <View
                            style={{
                                marginHorizontal: 8,
                                flexShrink: 1,
                                flexDirection: "row",
                                marginBottom: 8
                            }}
                        >
                            <View style={{ flexShrink: 1 }}>
                                <Like />
                            </View>
                            <View style={{ flexShrink: 1, marginRight: 8 }}>
                                <CommentIcon />
                            </View>
                            <View style={{ flexShrink: 1 }}>
                                <ShareIcon userHandle={detCtx.item.user_handle} takeId={detCtx.item._id} />
                            </View>
                            
                            
                        </View>
                        <View style={{ flexShrink: 1, margin: 8 }}>
                            <Text>{detCtx.item.item_text}</Text>
                        </View>
                        <CommentContextProvider>
                            <View style={{ flex: 1 }}>
                                <View style={{ flex: 1, width: "100%", alignItems: "center" }}>
                                    <CommentsSection setShowThumbnail={() => {}} item={detCtx.item} />
                                </View>
                                {/* <CommentPostInput imageData={imageData} />
                                <Animated.View style={[{ paddingBottom: keyboardHeight }]} /> */}
                            </View>
                        </CommentContextProvider>
                    </View>
                )}
            </View>
        </Animated.View>
    );```

Is there a way that I can just have the user interact with the purple section (backgroundColor: 'purple') to pull the card up or down? So that I can still use the flatlist within it? Or is that just not really possible. We're looking at other ways of presenting this, too, I was just curious if it could be done so that I can present it as an option. 

The above kind of works, it just doesn't work the way I would expect it to, all the time. 

Thanks fr any help you can give!
0 Answers
Related