I've been trying to use it with react-native-modal to achieve the same result as the Twitter/Facebook Gallery, where I can close modal by swiping down. But every time I try to use it I end up having a conflict between swipes.
Is there a way to fix it? Or even achieve the result using react-native's own modal? Ty
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { Text, View } from 'react-native';
import { useSharedValue } from 'react-native-reanimated';
import { Gallery, type GalleryType } from 'react-native-zoom-toolkit';
import {
getAssetsAsync,
requestPermissionsAsync,
type Asset,
} from 'expo-media-library';
import GalleryImage from './GalleryImage';
import { StyleSheet } from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import Modal from 'react-native-modal';
type SizeVector = { width: number; height: number };
const GalleryExample = () => {
const ref = useRef<GalleryType>(null);
const [assets, setAssets] = useState<Asset[]>([]);
const [scales, setScales] = useState<SizeVector[]>([]);
const [open, setOpen] = useState<boolean>(false);
const activeIndex = useSharedValue<number>(0);
const renderItem = useCallback(
(item: Asset, index: number) => {
return (
<GalleryImage asset={item} index={index} activeIndex={activeIndex} />
);
},
[activeIndex]
);
useEffect(() => {
const requestAssets = async () => {
const { granted } = await requestPermissionsAsync();
if (granted) {
const page = await getAssetsAsync({
first: 100,
mediaType: 'photo',
sortBy: 'creationTime',
});
const pageScales: SizeVector[] = [];
for (let asset of page.assets) {
pageScales.push({ width: asset.width, height: asset.height });
}
setAssets(page.assets);
setScales(pageScales);
}
};
requestAssets();
}, []);
if (assets.length === 0 || scales.length === 0) {
return null;
}
return (
<View style={styles.container}>
<Text>Open</Text>
<TouchableOpacity onPress={() => setOpen(true)}>
<Text>Open</Text>
</TouchableOpacity>
<Modal
isVisible={open}
style={styles.root}
onSwipeComplete={() => setOpen(false)}
onBackButtonPress={() => setOpen(false)}
>
<Gallery
ref={ref}
data={assets}
keyExtractor={(item, index) => `${item.uri}-${index}`}
renderItem={renderItem}
maxScale={scales}
onIndexChange={(idx) => {
activeIndex.value = idx;
}}
/>
</Modal>
</View>
);
};
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: '#000000',
margin: 0,
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'white',
},
});
export default GalleryExample;