react-native-awesome-gallery icon indicating copy to clipboard operation
react-native-awesome-gallery copied to clipboard

^0.3.8 Wrong positions when more than 1 image

Open FrSenpai opened this issue 1 year ago • 10 comments

Hey again!

I'm not using expo image, I don't know if it can be related, but when I've got more than 1 image into my data, it's not showing correctly the gallery content.

Capture d'écran 2023-12-22 161233

My component:

<GestureHandlerRootView>
                <AwesomeGallery
                    data={form.images.map(image => {
                        return {
                            uri: `data:image/png;base64,${fromByteArray(
                                image
                            )}`,
                        }
                    })}
                    keyExtractor={item => item.uri}
                    renderItem={renderItem}
                    initialIndex={0}
                    numToRender={3}
                    doubleTapInterval={150}
                    onIndexChange={() => {
                        //
                    }}
                    onSwipeToClose={() => {
                        //
                        setShowGallery(false)
                    }}
                    onTap={() => {
                        //
                    }}
                    loop
                    onScaleEnd={scale => {
                        if (scale < 0.8) {
                            //
                        }
                    }}
                />
</GestureHandlerRootView>

I'm using the same boilerplate as the example provided, tried a lot of params (played with loop, numToRender, onLoadEnd, onLoad, and more) but same result. But it's working perfectly when there is only 1 image.

Capture d'écran 2023-12-22 162512

I'm probably missing something, I'm sorry about it... Have a nice day!

FrSenpai avatar Dec 22 '23 15:12 FrSenpai

@FrSenpai What if you try keyExtractor={(item, i) => i}? Looks like you're passing base64 as a key in your example

pavelbabenko avatar Dec 22 '23 15:12 pavelbabenko

@FrSenpai How do you use renderItem?

pavelbabenko avatar Dec 22 '23 15:12 pavelbabenko

Same result with keyExtractor. Even if I'm removing renderItem, same result.

const renderItem = ({
    item,
    setImageDimensions,
}: RenderItemInfo<{uri: string}>): React.JSX.Element => {
    return (
        <Image
            source={{uri: item.uri}}
            style={StyleSheet.absoluteFillObject}
            resizeMode="contain"
            onLayout={e => {
                const {width, height} = e.nativeEvent.layout
                console.log('LAYOUT', width, height)
                setImageDimensions({width, height})
            }}
            
        />
    )
}

FrSenpai avatar Dec 22 '23 15:12 FrSenpai

@FrSenpai You should get image dimensions from onLoad, not from onLayout

onLoad={(e) => { const { width, height } = e.nativeEvent.source; setImageDimensions({ width, height }); }}

pavelbabenko avatar Dec 22 '23 15:12 pavelbabenko

Tried it too, and even onLoadEnd seems not work I'll try with FastImage, to check if it's related to Image of React Native

"react-native": "0.72.5", "react-native-reanimated": "^3.6.1",

Can it be related with not using flex ?

FrSenpai avatar Dec 22 '23 15:12 FrSenpai

Okay, it's definitly related of not using flex.

I don't think it should be required, but I understand that can be hard to avoid it

FrSenpai avatar Dec 22 '23 15:12 FrSenpai

@FrSenpai I think your GestureHandlerRootView should have style={{flex: 1}}

pavelbabenko avatar Dec 22 '23 15:12 pavelbabenko

`const MediaModalScreen = ({ media, index = 0, }: { media: PublicationMetadataMedia[]; index?: number; }) => { useStatusBarStyle('light-content'); const {goBack} = useAppNavigation(); const {scrollY, tabHeight} = useBottomTabView(); const screenSize = useScreenDimensions();

useFocusEffect( useCallback(() => { if (scrollY.value < tabHeight) { scrollY.value = withTiming(tabHeight); } }, [scrollY, tabHeight]), );

const {top} = useSafeAreaInsets();

const shareIndex = useSharedValue(index);

const total = useMemo(() => { return media ? media.length : 0; }, [media]);

const curCount = useDerivedValue( () => ${shareIndex.value + 1} / ${total}, [total], );

const renderItem = useCallback( ({ item, index: idx, setImageDimensions, }: RenderItemInfo<PublicationMetadataMedia>) => { return ( <RenderItem item={item} index={idx} share={idx === index} setImageDimensions={setImageDimensions} /> ); }, [index], ); return ( <View className="flex-1 bg-black"> <TouchableOpacity onPress={goBack} className="absolute right-4 top-0 z-50 h-10 w-10 items-center justify-center self-end rounded-full" style={{ marginTop: top + dp(14), backgroundColor: 'rgba(0, 0, 0, 0.5)', }}> <NwIcon name="close" size={dp(24)} className="text-white" /> </TouchableOpacity> <Gallery data={media} renderItem={renderItem} loop={false} onIndexChange={index => { shareIndex.value = index; }} initialIndex={index} containerDimensions={screenSize} onSwipeToClose={goBack} swipeRange={dp(200)} numToRender={2} style={{flex: 1}} keyExtractor={(_, index) => index.toString()} /> {total > 1 ? ( <View className="absolute bottom-0 z-50 self-center pb-2"> <ReText text={curCount} className="font-middle text-[1.125rem] leading-6 text-white" /> </View> ) : null} </View> ); };

export default MediaModalScreen;

const RenderItem = ({ item, share, setImageDimensions, }: RenderItemInfo<PublicationMetadataMedia> & {share: boolean}) => { const dimension = useScreenDimensions(); const {width = dimension.width, height = dimension.width} = getImageSizeFromMetadata(item) ?? {};

const url = useMemo( () => getUrlIfIpfs(getImageUriFromMetadata(item)), [item], );

const style = useMemo(() => { return { width: dimension.width, height: Math.min((dimension.width / width) * height, dimension.height), }; }, [dimension, width, height]);

return ( <View className="h-full w-full items-center justify-center"> {share ? ( <ShareImage style={style} contentFit="contain" onLoad={event => { const {width, height} = event.source; setImageDimensions({width, height}); }} source={{uri: url}} /> ) : ( <Image style={style} contentFit="contain" onLoad={event => { const {width, height} = event.source; setImageDimensions({width, height}); }} source={{uri: url}} /> )} </View> ); }; `I'm having the same issue

jingledongding avatar Feb 06 '24 15:02 jingledongding

please help

jingledongding avatar Feb 06 '24 15:02 jingledongding

You should remove alignItems: 'center' out of View, that includes your Gallery and add style={{flex: 1}} to GestureHandlerRootView Code example with the same problem:

export default function App() {
  return (
    <GestureHandlerRootView>
      <View style={styles.container}>
        <MyGallery/>
        <StatusBar style="auto" />
      </View>
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Working code example:

export default function App() {
  return (
    <GestureHandlerRootView style={{flex: 1}}>
      <View style={styles.container}>
        <MyGallery/>
        <StatusBar style="auto" />
      </View>
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    justifyContent: 'center',
  },
});

wDRxxx avatar Apr 05 '24 11:04 wDRxxx