New V Needed, improves cache and image handling

This commit is contained in:
Adolfo Reyna
2024-10-04 01:34:24 -04:00
parent dc52f57424
commit 461b8c98ed
7 changed files with 4149 additions and 123 deletions

View File

@@ -1,31 +1,36 @@
import React from 'react'; import React from 'react';
import { StyleSheet, TouchableHighlight, Image, TouchableWithoutFeedback, View } from 'react-native'; import { StyleSheet, View } from 'react-native';
import { Text, List, RadioButton } from "react-native-paper";
import { Image } from 'expo-image'; // Import Image from expo-image
let Slideshow = (props) => { let Slideshow = (props) => {
//console.log(route.params.postid) //console.log(route.params.postid)
//return <SinglePostComponent postId={route.params.postid} />; //return <SinglePostComponent postId={route.params.postid} />;
console.log(props) //console.log('RenderSlideSHow', props)
const images = props.route.params.images; const images = props.route.params.images;
[imageIndex, setImageIndex] = React.useState(props.route.params.startIndex); [imageIndex, setImageIndex] = React.useState(props.route.params.startIndex);
//images.length // images.length
console.log(imageIndex); // console.log(imageIndex);
console.log(images[imageIndex][1], images.length); // console.log(images[imageIndex][1], images.length);
let touchY = 0;
let touchX = 0;
return ( return (
<View <View
style={{ padding: 10, paddingTop: 20, flex: 1, justifyContent: "center" }} style={{ padding: 10, paddingTop: 20, flex: 1, justifyContent: "center" }}
onTouchStart={e => { onTouchStart={e => {
this.touchY = e.nativeEvent.pageY //console.log(e.nativeEvent)
this.touchX = e.nativeEvent.pageX touchY = e.nativeEvent.pageY
touchX = e.nativeEvent.pageX
}} }}
onTouchEnd={e => { onTouchEnd={e => {
if ((this.touchX - e.nativeEvent.pageX > 20) && (images.length - 1 > imageIndex)) if ((touchX - e.nativeEvent.pageX > 20) && (images.length - 1 > imageIndex))
setImageIndex(imageIndex + 1) setImageIndex(imageIndex + 1)
if ((this.touchX - e.nativeEvent.pageX < -20) && (imageIndex > 0)) if ((touchX - e.nativeEvent.pageX < -20) && (imageIndex > 0))
setImageIndex(imageIndex - 1) setImageIndex(imageIndex - 1)
}} }}
> >
<Image source={{ uri: images[imageIndex][1] }} key={images[imageIndex][1]} style={styles.image} /> <Text style={styles.countText}>{imageIndex+1}/{images.length}</Text>
<Image source={{ uri: images[imageIndex][1] }} key={images[imageIndex][1]} style={styles.image} cachePolicy="memory-disk"/>
</View> </View>
) )
}; };
@@ -36,6 +41,11 @@ const styles = StyleSheet.create({
height: "100%", height: "100%",
resizeMode: "contain", resizeMode: "contain",
}, },
countText: {
position: 'absolute',
left: '50%',
bottom: 10
}
}); });
export default Slideshow; export default Slideshow;

View File

@@ -45,7 +45,15 @@
}, },
"plugins": [ "plugins": [
[ [
"expo-notifications" "expo-notifications",
],
[
"expo-media-library",
{
"photosPermission": "Allow $(PRODUCT_NAME) to access your photos.",
"savePhotosPermission": "Allow $(PRODUCT_NAME) to save photos.",
"isAccessMediaLocationEnabled": true
}
], ],
"expo-localization" "expo-localization"
], ],

View File

@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { View, TouchableHighlight, Image, StyleSheet, FlatList, TouchableWithoutFeedback, Share } from 'react-native'; import { View, TouchableHighlight, StyleSheet, FlatList, TouchableWithoutFeedback, Share } from 'react-native';
import { Button, Text, ProgressBar } from 'react-native-paper'; import { Button, Text, ProgressBar } from 'react-native-paper';
import API from './../API.js'; import API from './../API.js';
import VideoPlayer from './VideoPlayer.js'; import VideoPlayer from './VideoPlayer.js';
@@ -9,6 +9,9 @@ import { useSnapshot } from 'valtio';
import GlobalState from '../contexts/GlobalState.js'; import GlobalState from '../contexts/GlobalState.js';
import Moment from 'moment'; import Moment from 'moment';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { Image } from 'expo-image'; // Import Image from expo-image
import * as FileSystem from 'expo-file-system';
import * as Sharing from 'expo-sharing';
const videoIdF = (content) => { const videoIdF = (content) => {
let vimeoTag = content.match(/@vimeo:[0-9]+/); let vimeoTag = content.match(/@vimeo:[0-9]+/);
@@ -41,7 +44,7 @@ const imagesTagF = (content) => {
images.forEach(i => { images.forEach(i => {
let tag = i.substring(1); let tag = i.substring(1);
let parts = [tag.substring(1, tag.indexOf(":")), tag.substring(tag.indexOf(":") + 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]; if (parts[1].substring(0, 4) != "http") parts[1] = "https://social.emmint.com/" + parts[1] + '?width=1000&height=1000';
Tags.push(parts); Tags.push(parts);
}); });
return Tags; return Tags;
@@ -60,6 +63,7 @@ let Media = (props) => {
const gState = useSnapshot(GlobalState); const gState = useSnapshot(GlobalState);
const viewer = gState.me; const viewer = gState.me;
const imagesTag = imagesTagF(props.content); const imagesTag = imagesTagF(props.content);
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 videosId = videoIdF(props.content);
const hlsUrl = hlsIdF(props.content); const hlsUrl = hlsIdF(props.content);
@@ -88,7 +92,7 @@ let Media = (props) => {
loaded ? <VideoPlayer videosFiles={videosFiles} poster={poster} videoId={videosId[1]} /> : loaded ? <VideoPlayer videosFiles={videosFiles} poster={poster} videoId={videosId[1]} /> :
( (
<TouchableHighlight onPress={() => setLoaded(true)}> <TouchableHighlight onPress={() => setLoaded(true)}>
<Image source={poster ? { uri: poster } : {}} key={poster} style={styles.poster} /> <Image source={poster ? { uri: poster } : {}} key={poster} style={styles.poster} cachePolicy="memory-disk" />
</TouchableHighlight> </TouchableHighlight>
) )
) : ) :
@@ -102,7 +106,7 @@ let Media = (props) => {
GlobalState.mediaPost = props.post; GlobalState.mediaPost = props.post;
}}> }}>
{poster ? {poster ?
<Image source={poster ? { uri: poster } : {}} key={poster} style={styles.poster} /> : <Image source={poster ? { uri: poster } : {}} key={poster} style={styles.poster} cachePolicy="memory-disk" /> :
<Button <Button
icon={"subscriptions"} icon={"subscriptions"}
labelStyle={{ fontSize: 58 }} labelStyle={{ fontSize: 58 }}
@@ -134,7 +138,7 @@ let Media = (props) => {
url: item[1], url: item[1],
}); });
}}> }}>
<Image source={{ uri: item[1] }} style={styles.flatlistImages} /> <Image source={{ uri: item[1] }} style={styles.flatlistImages} cachePolicy="memory-disk" />
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
); );
}); });
@@ -148,6 +152,18 @@ let Media = (props) => {
<ProgressBar progress={viewer.data[props.postId].time / viewer.data[props.postId].duration} /> <ProgressBar progress={viewer.data[props.postId].time / viewer.data[props.postId].duration} />
</>; </>;
} }
const shareImage = async (imageUrl) => {
try {
// Download the image to the device's file system
const fileUri = `${FileSystem.cacheDirectory}shared-image.jpg`;
const { uri } = await FileSystem.downloadAsync(imageUrl, fileUri);
// Share the downloaded image
await Sharing.shareAsync(uri);
} catch (error) {
console.error("Error sharing the image", error);
}
};
return ( return (
<View <View
style={{ style={{
@@ -159,7 +175,7 @@ let Media = (props) => {
(imagesTag.length > 2) ? (imagesTag.length > 2) ?
<FlatList <FlatList
horizontal={true} horizontal={true}
data={imagesTag} data={imagesTagLimited}
renderItem={renderImages} renderItem={renderImages}
keyExtractor={item => item[1]} keyExtractor={item => item[1]}
initialNumToRender={2} initialNumToRender={2}
@@ -181,13 +197,14 @@ let Media = (props) => {
onPress={() => { onPress={() => {
navigation.navigate('Slideshow', { images: imagesTag, startIndex: i }); navigation.navigate('Slideshow', { images: imagesTag, startIndex: i });
}} }}
onLongPress={() => { onLongPress={async () => {
Share.share({ await shareImage(image[1]);
//Share.share({
//message: image[1], //message: image[1],
url: image[1], // url: image[1],
}); //});
}}> }}>
<Image source={{ uri: image[1] }} key={image[1]} style={imageStyle} /> <Image source={{ uri: image[1] }} key={image[1]} style={imageStyle} cachePolicy="memory-disk" />
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
) )
}) })

View File

@@ -7,7 +7,7 @@ import FollowButton from './basics/FollowButton';
const DefaultPhoto = "https://social.emmint.com/uploads/e6f9be6d665dc43417701bf16a90122c.png"; const DefaultPhoto = "https://social.emmint.com/uploads/e6f9be6d665dc43417701bf16a90122c.png";
const ProfileHeader = ({ profileObj }) => { const ProfileHeader = ({ profileObj }) => {
let photoUrl = profileObj.profile && profileObj.profile.photo ? 'https://social.emmint.com/' + profileObj.profile.photo : DefaultPhoto; let photoUrl = profileObj.profile && profileObj.profile.photo ? 'https://social.emmint.com/' + profileObj.profile.photo + '?width=1000&height=1000' : DefaultPhoto;
return ( return (
<> <>
<Card elevation={3}> <Card elevation={3}>

View File

@@ -3,8 +3,9 @@ import { Avatar } from 'react-native-paper';
import { View, StyleSheet, Text } from 'react-native'; import { View, StyleSheet, Text } from 'react-native';
import API from './../API.js'; import API from './../API.js';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { Image } from 'expo-image'; // Import Image from expo-image
const DefaultPhoto = "https://social.emmint.com/uploads/e6f9be6d665dc43417701bf16a90122c.png"; const DefaultPhoto = "https://social.emmint.com/uploads/e6f9be6d665dc43417701bf16a90122c.png?width=200&height=200";
const ProfileHeader = ({ profileid, withName = false, small = false }) => { const ProfileHeader = ({ profileid, withName = false, small = false }) => {
let [profile, setProfile] = useState({}); let [profile, setProfile] = useState({});
@@ -21,16 +22,20 @@ const ProfileHeader = ({ profileid, withName = false, small = false }) => {
subscribed = false; subscribed = false;
}; };
}, [profileid]); }, [profileid]);
let photoUrl = profile.profile && profile.profile.photo ? 'https://social.emmint.com/' + profile.profile.photo : DefaultPhoto; let photoUrl = profile.profile && profile.profile.photo ? 'https://social.emmint.com/' + profile.profile.photo + '?width=100&height=100' : DefaultPhoto;
const fullName = " " + profile.profile?.firstName + " " + profile.profile?.lastName; const fullName = " " + profile.profile?.firstName + " " + profile.profile?.lastName;
const onPress = () => { const onPress = () => {
return navigation.navigate('Profile', { profileid }) return navigation.navigate('Profile', { profileid })
} }
return ( return (
<View style={styles.container}> <View style={styles.container}>
<View style={styles.avatarContainer}> <Image source={{ uri: photoUrl }} key={photoUrl}
<Avatar.Image size={small ? 20 : 35} source={{ uri: photoUrl }} onPress={onPress} style={{marginLeft:-4}}/> style={{
</View> width: small ? 25 : 35,
height: small ? 25 : 35,
aspectRatio: 1,
borderRadius: 50,
}} cachePolicy="memory-disk"/>
<View style={styles.textContainer}> <View style={styles.textContainer}>
<Text style={small ? styles.smallProfileName : styles.profileName} onPress={onPress}>{fullName}</Text> <Text style={small ? styles.smallProfileName : styles.profileName} onPress={onPress}>{fullName}</Text>
</View> </View>

4168
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -40,7 +40,11 @@
"react-native-web": "~0.19.6", "react-native-web": "~0.19.6",
"react-native-webview": "13.2.2", "react-native-webview": "13.2.2",
"valtio": "^1.4.0", "valtio": "^1.4.0",
"@expo/metro-config": "~0.10.0" "@expo/metro-config": "~0.10.0",
"@expo/webpack-config": "^19.0.0",
"expo-image": "~1.3.5",
"expo-media-library": "~15.4.1",
"expo-sharing": "~11.5.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.19.3" "@babel/core": "^7.19.3"