Files
EMI-ExpoAPP/Views/Slideshow.js
2024-10-05 21:30:34 -04:00

187 lines
6.4 KiB
JavaScript

import React, { useRef } from 'react';
import { StyleSheet, View, Text, Animated, PanResponder, Dimensions, FlatList, TouchableOpacity } from 'react-native';
import { Image } from 'expo-image'; // Import Image from expo-image
import { Button } from 'react-native-paper';
import * as Sharing from 'expo-sharing';
import * as FileSystem from 'expo-file-system';
const { width: SCREEN_WIDTH } = Dimensions.get('window');
let Slideshow = (props) => {
const images = props.route.params.images;
const imagesTumb = images.map((imageUrl) => imageUrl[1] + '?width=100&height=100`');
const [imageIndex, setImageIndex] = React.useState(props.route.params.startIndex);
// Animated value for horizontal translation
const translateX = useRef(new Animated.Value(0)).current;
const panResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponder: (_, gestureState) => Math.abs(gestureState.dx) > 10,
onPanResponderMove: Animated.event(
[null, { dx: translateX }],
{ useNativeDriver: false }
),
onPanResponderRelease: (_, gestureState) => {
if (gestureState.dx < -SCREEN_WIDTH / 4) {
// Swipe left: Move to the next image
Animated.timing(translateX, {
toValue: -SCREEN_WIDTH,
duration: 300,
useNativeDriver: false,
}).start(() => {
setImageIndex((prevIndex) => {
if (prevIndex < (images.length - 1))
return prevIndex + 1;
return prevIndex;
});
translateX.setValue(0);
});
} else if (gestureState.dx > SCREEN_WIDTH / 4) {
// Swipe right: Move to the previous image
Animated.timing(translateX, {
toValue: SCREEN_WIDTH,
duration: 300,
useNativeDriver: false,
}).start(() => {
setImageIndex((prevIndex) => {
if (prevIndex > 0)
return prevIndex - 1
return prevIndex
});
translateX.setValue(0);
});
} else {
// If not enough swipe distance, reset position
Animated.spring(translateX, {
toValue: 0,
useNativeDriver: false,
}).start();
}
},
})
).current;
const shareImage = async () => {
try {
const fileUri = FileSystem.documentDirectory + 'shared_image.jpg';
const { uri } = await FileSystem.downloadAsync(images[imageIndex][1], fileUri);
await Sharing.shareAsync(uri);
} catch (error) {
console.error(error)
}
};
const repostImage = () => {
props.navigation.navigate('NewPost', { intialContent: '@image:' + images[imageIndex][1] });
};
return (
<View style={styles.container}>
<Text style={styles.countText}>{imageIndex + 1}/{images.length}</Text>
<Animated.View
style={[
styles.imageContainer,
{ transform: [{ translateX }] },
]}
{...panResponder.panHandlers}
>
<Image
source={{ uri: images[imageIndex][1] }}
key={images[imageIndex][1]}
style={styles.image}
cachePolicy="memory-disk"
/>
</Animated.View>
{/* Share and Repost Buttons */}
<View style={styles.buttonsContainer}>
<Button icon="ios-share" labelStyle={{ fontSize: 25 }} style={{ margin:10 }}
onPress={shareImage}
color="#555"
></Button>
<Button icon="send" labelStyle={{ fontSize: 25 }} style={{ }}
onPress={repostImage}
color="#555"
></Button>
</View>
{/* Thumbnails */}
<FlatList
data={imagesTumb}
horizontal
keyExtractor={(item, index) => index.toString()}
renderItem={({ item, index }) => (
<TouchableOpacity onPress={() => {
setImageIndex(index);
}}>
<Image
source={{ uri: item }}
style={[
styles.thumbnail,
imageIndex === index && styles.currentThumbnail
]}
cachePolicy="memory-disk"
/>
</TouchableOpacity>
)}
initialNumToRender={6}
style={styles.thumbnailList}
showsHorizontalScrollIndicator={false}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
padding: 0,
paddingTop: 0,
},
imageContainer: {
width: SCREEN_WIDTH,
height: '100%',
justifyContent: 'center',
alignItems: 'center',
},
image: {
width: '100%',
height: '100%',
contentFit: "contain",
},
countText: {
position: 'absolute',
left: '45%',
top: 10,
color: '#000',
zIndex: 1000,
backgroundColor: 'rgba(255, 255, 255, 0.5)',
padding: 10,
},
buttonsContainer: {
flexDirection: 'column',
justifyContent: 'space-around',
position: 'absolute',
right: -20,
bottom: 90,
paddingHorizontal: 10,
},
thumbnailList: {
position: 'absolute',
bottom: 15,
width: '100%',
paddingHorizontal: 10,
},
thumbnail: {
width: 60,
height: 60,
marginHorizontal: 5,
borderRadius: 10,
borderWidth: 2,
borderColor: 'white',
},
currentThumbnail: {
borderColor: 'rgba(50,255,50,0.8)',
},
});
export default Slideshow;