diff --git a/Views/Slideshow.js b/Views/Slideshow.js
index cb2861f..a54237e 100644
--- a/Views/Slideshow.js
+++ b/Views/Slideshow.js
@@ -1,7 +1,7 @@
import React, { useRef } from 'react';
-import { StyleSheet, View, Text, Animated, PanResponder, Dimensions, TouchableOpacity } from 'react-native';
+import { StyleSheet, View, Text, Animated, PanResponder, Dimensions, FlatList, TouchableOpacity } from 'react-native';
import { Image } from 'expo-image'; // Import Image from expo-image
-import { Button, Card, Chip } from 'react-native-paper';
+import { Button } from 'react-native-paper';
import * as Sharing from 'expo-sharing';
import * as FileSystem from 'expo-file-system';
@@ -9,6 +9,7 @@ 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
@@ -47,8 +48,7 @@ let Slideshow = (props) => {
if (prevIndex > 0)
return prevIndex - 1
return prevIndex
- }
- );
+ });
translateX.setValue(0);
});
} else {
@@ -68,30 +68,16 @@ let Slideshow = (props) => {
const { uri } = await FileSystem.downloadAsync(images[imageIndex][1], fileUri);
await Sharing.shareAsync(uri);
} catch (error) {
- //Alert.alert('Error', 'Failed to share image. Please try again later.');
console.error(error)
}
};
const repostImage = () => {
- // Repost logic goes here (for now, just showing an alert)
- //Alert.alert('Repost', 'Repost functionality is not yet implemented.');
props.navigation.navigate('NewPost', { intialContent: '@image:' + images[imageIndex][1] });
};
return (
{imageIndex + 1}/{images.length}
-
- {/* Left arrow */}
- {(imageIndex > 0) && (
- {'|'}
- )}
-
- {/* Right arrow */}
- {imageIndex < images.length - 1 && (
- {'|'}
- )}
-
{
{/* Share and Repost Buttons */}
-
-
+ {/* Thumbnails */}
+ index.toString()}
+ renderItem={({ item, index }) => (
+ {
+ setImageIndex(index);
+ }}>
+
+
+ )}
+ initialNumToRender={6}
+ style={styles.thumbnailList}
+ showsHorizontalScrollIndicator={false}
+ />
);
};
@@ -148,37 +157,31 @@ const styles = StyleSheet.create({
backgroundColor: 'rgba(255, 255, 255, 0.5)',
padding: 10,
},
- arrow: {
- position: 'absolute',
- top: '45%',
- fontSize: 40,
- color: 'rgba(255, 255, 255, 0.7)',
- zIndex: 1,
- },
- leftArrow: {
- left: 10,
- },
- rightArrow: {
- right: 10,
- },
buttonsContainer: {
- flexDirection: 'row',
+ flexDirection: 'column',
justifyContent: 'space-around',
position: 'absolute',
- bottom: 20,
+ right: -20,
+ bottom: 90,
+ paddingHorizontal: 10,
+ },
+ thumbnailList: {
+ position: 'absolute',
+ bottom: 15,
width: '100%',
- paddingHorizontal: 20,
+ paddingHorizontal: 10,
},
- button: {
- paddingVertical: 10,
- paddingHorizontal: 20,
- backgroundColor: 'rgba(255, 255, 255, 0.7)',
- borderRadius: 5,
+ thumbnail: {
+ width: 60,
+ height: 60,
+ marginHorizontal: 5,
+ borderRadius: 10,
+ borderWidth: 2,
+ borderColor: 'white',
},
- buttonText: {
- color: '#fff',
- fontSize: 16,
+ currentThumbnail: {
+ borderColor: 'rgba(50,255,50,0.8)',
},
});
-export default Slideshow;
+export default Slideshow;
\ No newline at end of file
diff --git a/components/Media.js b/components/Media.js
index 4cd7744..f63991e 100644
--- a/components/Media.js
+++ b/components/Media.js
@@ -1,3 +1,4 @@
+// Import necessary dependencies
import React, { useState, useEffect } from 'react';
import { View, TouchableHighlight, StyleSheet, FlatList, TouchableWithoutFeedback, Share } from 'react-native';
import { Button, Text, ProgressBar } from 'react-native-paper';
@@ -13,6 +14,7 @@ import { Image } from 'expo-image'; // Import Image from expo-image
import * as FileSystem from 'expo-file-system';
import * as Sharing from 'expo-sharing';
+// Extract Vimeo video ID from content string
const videoIdF = (content) => {
let vimeoTag = content.match(/@vimeo:[0-9]+/);
if (!vimeoTag) return [];
@@ -21,6 +23,7 @@ const videoIdF = (content) => {
return tag.split(':');
};
+// Extract YouTube video ID from content string
const youtubeIdF = (content) => {
let youtubeTag = content.match(/@youtube:[0-z]+/);
if (!youtubeTag) return '';
@@ -29,6 +32,7 @@ const youtubeIdF = (content) => {
return tag.split(':')[1];
};
+// Extract HLS URL from content string
const hlsIdF = (content) => {
let hslTag = content.match(/@hls:.+\w/);
if (!hslTag) return '';
@@ -37,19 +41,21 @@ const hlsIdF = (content) => {
return tag;
};
-const imagesTagF = (content) => {
+// Extract image tags from content string
+const imagesTagF = (content, width = 1000, height = 1000) => {
let images = content.match(/@image:[0-z|/|.|]+/g);
if (!images) return [];
let Tags = [];
images.forEach(i => {
let tag = i.substring(1);
let parts = [tag.substring(1, tag.indexOf(":")), tag.substring(tag.indexOf(":") + 1)];
- if (parts[1].substring(0, 4) != "http") parts[1] = "https://social.emmint.com/" + parts[1] + '?width=1000&height=1000';
+ if (parts[1].substring(0, 4) != "http") parts[1] = `https://social.emmint.com/${parts[1]}?width=${width}&height=${height}`;
Tags.push(parts);
});
return Tags;
};
+// Extract iframe source from content string
const iframeTagF = (content) => {
let iframeMatch = content.match(/@iframe:.+\w/g);
if (!iframeMatch) return [];
@@ -58,25 +64,32 @@ const iframeTagF = (content) => {
return parts;
};
-
+// Media Component
let Media = (props) => {
const gState = useSnapshot(GlobalState);
const viewer = gState.me;
- const imagesTag = imagesTagF(props.content);
+
+ // Extracting tags from content
+ const imagesTag = imagesTagF(props.content, props.imageWidth || 1000, props.imageHeight || 1000);
const imagesTagLimited = imagesTag.slice(0, 10);
- const imageStyle = imagesTag.length == 1 ? styles.image : styles.multipleImage;
+ const imageStyle = imagesTag.length === 1 ? styles.image : styles.multipleImage;
const videosId = videoIdF(props.content);
const hlsUrl = hlsIdF(props.content);
const iframeSrc = iframeTagF(props.content) || [];
const youtubeId = youtubeIdF(props.content);
+
const [videosFiles, setVideosFiles] = useState([]);
const [poster, setPoster] = useState('');
const [loaded, setLoaded] = useState(false);
const navigation = useNavigation();
+
+ let interactive = props.interactive || true;
+
+ // Fetch video data from API
useEffect(() => {
let subscribed = true;
let getData = async () => {
- if (!videosId[1]) return 0;
+ if (!videosId[1]) return;
let videoObj = await API.getVideo(videosId[1]);
if (videoObj && videoObj.files && subscribed) {
setVideosFiles(videoObj.files);
@@ -87,69 +100,95 @@ let Media = (props) => {
return () => {
subscribed = false;
};
- }, [props.content])
- const video = (videosFiles.length && !props.skiptVideo) ? (
- loaded ? :
- (
+ }, [props.content]);
+
+ // Render video component
+ const renderVideo = () => {
+ if (videosFiles.length && !props.skiptVideo) {
+ return loaded ? (
+
+ ) : (
setLoaded(true)}>
- )
- ) :
- (videosId.length ? : <>>);
- const video2 = (hlsUrl && !props.skiptVideo) ? (
- loaded ?
- :
- {
- //setLoaded(true)
- GlobalState.currentMedia = hlsUrl;
- GlobalState.mediaPost = props.post;
- }}>
- {poster ?
- :
-
- }
-
- ) : <>>;
- const iframe = iframeSrc.length ?
- : <>>;
- const youtubeEmb = youtubeId.length ?
- : <>>;
- const renderImages = (({ item, index }) => {
- return (
- {
- //alert("hello");
- navigation.navigate('Slideshow', { images: imagesTag, startIndex: index });
- }}
- onLongPress={async () => {
- await shareImage(item[1]);
+ );
+ }
+ if (videosId.length) {
+ return ;
+ }
+ return null;
+ };
+
+ // Render HLS video component
+ const renderHlsVideo = () => {
+ if (hlsUrl && !props.skiptVideo) {
+ return loaded ? (
+
+ ) : (
+ {
+ GlobalState.currentMedia = hlsUrl;
+ GlobalState.mediaPost = props.post;
}}>
-
-
- );
- });
- let progress = <>>;
- if (viewer.data && viewer.data[props.postId]) {
- const percent = Math.round(viewer.data[props.postId].time / viewer.data[props.postId].duration * 100);
- if (percent)
- progress =
- <>
- {percent}% {Moment(viewer.data[props.postId].ts).fromNow()}
-
- >;
- }
+ {poster ? (
+
+ ) : (
+
+ )}
+
+ );
+ }
+ return null;
+ };
+
+ // Render iframe component
+ const renderIframe = () => {
+ if (iframeSrc.length) {
+ return (
+
+ );
+ }
+ return null;
+ };
+
+ // Render YouTube embed component
+ const renderYouTubeEmbed = () => {
+ if (youtubeId.length) {
+ return (
+
+ );
+ }
+ return null;
+ };
+
+ // Render progress bar if available
+ const renderProgressBar = () => {
+ if (viewer.data && viewer.data[props.postId]) {
+ const percent = Math.round(viewer.data[props.postId].time / viewer.data[props.postId].duration * 100);
+ if (percent) {
+ return (
+ <>
+ {percent}% {Moment(viewer.data[props.postId].ts).fromNow()}
+
+ >
+ );
+ }
+ }
+ return null;
+ };
+
+ // Function to share an image
const shareImage = async (imageUrl) => {
+ if (!interactive) return;
try {
// Download the image to the device's file system
const fileUri = `${FileSystem.cacheDirectory}shared-image.jpg`;
@@ -161,64 +200,69 @@ let Media = (props) => {
console.error("Error sharing the image", error);
}
};
- return (
- {
+ if (!interactive) return;
+ navigation.navigate('Slideshow', { images: imagesTag, startIndex: index });
+ };
+
+ // Render images in a FlatList
+ const renderImages = ({ item, index }) => (
+ navigateToSlideshow(index)}
+ onLongPress={async () => {
+ await shareImage(item[1]);
}}
>
- {
- (imagesTag.length > 2) ?
- item[1]}
- initialNumToRender={2}
- style={{
- transform: [{
- scale: 1.1
- }],
- paddingTop: 5,
- paddingBottom: 10,
- }}
- showsHorizontalScrollIndicator={false}
- /> :
-
- {
- imagesTag.map((image, i) => {
- return (
- //{post.content}
- {
- navigation.navigate('Slideshow', { images: imagesTag, startIndex: i });
- }}
- onLongPress={async () => {
- await shareImage(image[1]);
- //Share.share({
- //message: image[1],
- // url: image[1],
- //});
- }} key={image[1]}>
-
-
- )
- })
- }
-
- }
- {video}
- {video2}
- {iframe}
- {youtubeEmb}
- {progress}
+
+
+ );
+
+ return (
+
+ {imagesTag.length > 2 ? (
+ item[1]}
+ initialNumToRender={2}
+ style={{
+ transform: [{ scale: 1.1 }],
+ paddingTop: 5,
+ paddingBottom: 10,
+ }}
+ showsHorizontalScrollIndicator={false}
+ />
+ ) : (
+
+ {imagesTag.map((image, i) => (
+ navigateToSlideshow(i)}
+ onLongPress={async () => {
+ await shareImage(image[1]);
+ }}
+ >
+
+
+ ))}
+
+ )}
+ {renderVideo()}
+ {renderHlsVideo()}
+ {renderIframe()}
+ {renderYouTubeEmbed()}
+ {renderProgressBar()}
);
-}
+};
export default Media;
+// Styles for different media components
const styles = StyleSheet.create({
image: {
width: "100%",
@@ -245,4 +289,4 @@ const styles = StyleSheet.create({
width: "100%",
minHeight: 300,
}
-});
+});
\ No newline at end of file