This commit is contained in:
Adolfo Reyna
2022-11-21 15:46:36 -05:00
11 changed files with 9893 additions and 6853 deletions

20
API.js
View File

@@ -114,9 +114,15 @@ const API = {
return data; return data;
}); });
}, },
async subscribe(subscription){
return postCall("/subscribe", subscription);
},
resetPassword(email){ resetPassword(email){
return postCall("/resetPassword", {username: email}); return postCall("/resetPassword", {username: email});
}, },
changePassword(newPassword){
return postCall("/resetPassword", {password: newPassword});
},
currentUserId() { currentUserId() {
if (!CurrentUserId) this.isLoggedIn(); //replace with cookie if (!CurrentUserId) this.isLoggedIn(); //replace with cookie
return CurrentUserId; return CurrentUserId;
@@ -141,6 +147,9 @@ const API = {
deletePost(postid){ deletePost(postid){
return deleteCall("/post/" + postid); return deleteCall("/post/" + postid);
}, },
updatePost(post){
return postCall("/post/" + post._id, {content: post.content});
},
newPost(content, toProfile, isNews) { newPost(content, toProfile, isNews) {
//Content is expected to be a string. //Content is expected to be a string.
let params = { content }; let params = { content };
@@ -167,6 +176,9 @@ const API = {
newCommentReaction(postid, commentDate) { newCommentReaction(postid, commentDate) {
return postCall("/post/comment/react", { postid, commentDate }); return postCall("/post/comment/react", { postid, commentDate });
}, },
removeCommentReaction(postid, commentDate) {
return postCall("/post/comment/unreact", { postid, commentDate });
},
//Invitations //Invitations
newInvitation(name, email){ newInvitation(name, email){
return postCall("/user/invite", { name, email }); return postCall("/user/invite", { name, email });
@@ -267,16 +279,20 @@ const API = {
getGroup(groupid) { getGroup(groupid) {
return getCall("/user/groups/" + groupid); return getCall("/user/groups/" + groupid);
}, },
subscribeToGroup(groupid){ async subscribeToGroup(groupid){
return getCall("/user/groups/" + groupid + "/subscribe"); delete userNameCache[groupid];
return await getCall("/user/groups/" + groupid + "/subscribe");
}, },
acceptGroupRequest(profileid, groupid){ acceptGroupRequest(profileid, groupid){
delete userNameCache[groupid];
return postCall("/user/groups/accept", {profileid, groupid}); return postCall("/user/groups/accept", {profileid, groupid});
}, },
rejectGroupRequest(profileid, groupid){ rejectGroupRequest(profileid, groupid){
delete userNameCache[groupid];
return postCall("/user/groups/reject", {profileid, groupid}); return postCall("/user/groups/reject", {profileid, groupid});
}, },
unsubscribeToGroup(groupid){ unsubscribeToGroup(groupid){
delete userNameCache[groupid];
return getCall("/user/groups/" + groupid + "/unsubscribe"); return getCall("/user/groups/" + groupid + "/unsubscribe");
}, },
//Payments //Payments

8
App.js
View File

@@ -109,7 +109,7 @@ const MainNavigation = () => {
activeColor="#0d6efd" activeColor="#0d6efd"
inactiveColor="#FFFFFF" inactiveColor="#FFFFFF"
barStyle={{ backgroundColor: '#000000' }} barStyle={{ backgroundColor: '#000000' }}
sceneContainerStyle={{paddingBottom: 0}} sceneContainerStyle={{paddingBottom: 0, paddingTop: 15}}
> >
<Tab.Screen <Tab.Screen
name="Feed" name="Feed"
@@ -198,7 +198,11 @@ export default function App() {
<Stack.Screen <Stack.Screen
name="MainNavigation" name="MainNavigation"
component={MainNavigation} component={MainNavigation}
options={{ headerShown: true }} options={{
headerShown: true,
tabBarLabel: 'EMI Social',
header: ()=>{<></>},
}}
/> />
<Stack.Screen <Stack.Screen
name="Profile" name="Profile"

View File

@@ -31,26 +31,37 @@ const getFeed = async () => {
let Feed = ({ navigation, route }) => { let Feed = ({ navigation, route }) => {
let [Posts, setPosts] = useState([]); let [Posts, setPosts] = useState([]);
console.log("Render Feed"); console.log("Render Feed");
useEffect(async () => { useEffect(() => {
let subscribed = true;
const getData = async () => {
let loggedIn = await API.isLoggedIn(); let loggedIn = await API.isLoggedIn();
if (!loggedIn) return navigation.reset({ if (!loggedIn) return navigation.reset({
index: 0, index: 0,
routes: [{ name: 'Login' }], routes: [{ name: 'Login' }],
}); });
if (route.params && route.params.profileid) { if (route.params && route.params.profileid) {
navigation.navigate('Profile', { profileid: route.params.profileid }) return navigation.navigate('Profile', { profileid: route.params.profileid })
} }
API.getMe().then((me) => { API.getMe().then((me) => {
if (subscribed)
GlobalState.me = me; GlobalState.me = me;
}); });
console.log("Feed from cache") console.log("Feed from cache")
let cacheFeed = await getFeed() || []; let cacheFeed = await getFeed() || [];
if(cacheFeed.length) setPosts(cacheFeed); if (cacheFeed.length && subscribed) setPosts(cacheFeed);
console.log("Feed from server") console.log("Feed from server")
let posts = await API.getPosts(); let posts = await API.getPosts();
if (subscribed) {
setPosts(posts); setPosts(posts);
storeFeed(posts); storeFeed(posts);
}
console.log("Feed, end useEffect") console.log("Feed, end useEffect")
}
getData()
return () => {
subscribed = false;
}
}, [route.params]); }, [route.params]);
const renderPost = (({ item }) => { const renderPost = (({ item }) => {
if (item.nonOrganicType === 'PopularUsers' || item.nonOrganicType === 'PopularGroups') if (item.nonOrganicType === 'PopularUsers' || item.nonOrganicType === 'PopularGroups')

View File

@@ -5,12 +5,18 @@ import API from './../API.js';
import LoginForm from './../components/Login.js'; import LoginForm from './../components/Login.js';
export default function App({navigation, route}) { export default function App({navigation, route}) {
useEffect(async () => { useEffect(()=>{
getData = async () => {
let r = await API.isLoggedIn(); let r = await API.isLoggedIn();
if(r){ if(r){
await API.logout(); await API.logout();
navigation.navigate('Login') navigation.navigate('Login')
} }
}
getData();
return ()=>{
}
}, []); }, []);
return ( return (

View File

@@ -5,6 +5,7 @@ import API from './../API.js';
import Post from './../components/Post.js'; import Post from './../components/Post.js';
import NewPost from "./../components/NewPost.js"; import NewPost from "./../components/NewPost.js";
import ProfileHeader from '../components/ProfileHeader.js'; import ProfileHeader from '../components/ProfileHeader.js';
import AsyncStorage from '@react-native-async-storage/async-storage';
const storeProfilePosts = async (profileid, value) => { const storeProfilePosts = async (profileid, value) => {
try { try {
@@ -22,6 +23,7 @@ const getProfilePosts = async (profileid) => {
} }
return []; return [];
} catch (e) { } catch (e) {
console.log('fail getProfilePosts', e)
return []; return [];
} }
} }
@@ -30,18 +32,22 @@ let Profile = ({ navigation, route }) => {
let [Posts, setPosts] = useState([]); let [Posts, setPosts] = useState([]);
let [profile, setProfile] = useState({}); let [profile, setProfile] = useState({});
useEffect(async () => { useEffect(() => {
let subscribed = true;
const getData = async () => {
setPosts([]); setPosts([]);
if (route.params && route.params.profileid) { if (route.params && route.params.profileid) {
console.log('Loading Cache Profile:' + route.params.profileid); console.log('Loading Cache Profile:' + route.params.profileid);
getProfilePosts(route.params.profileid).then(setPosts); await API.getUserProfile(route.params.profileid).then((profileObj) => {
console.log('Loaded Cache Profile:' + route.params.profileid); if(!subscribed) return 0;
API.getUserProfile(route.params.profileid).then((profileObj) => {
let profile = profileObj.profile let profile = profileObj.profile
setProfile(profileObj); setProfile(profileObj);
navigation.setOptions({ title: profile.firstName + " " + profile.lastName }); navigation.setOptions({ title: profile.firstName + " " + profile.lastName });
}); });
await getProfilePosts(route.params.profileid).then(setPosts);
console.log('Loaded Cache Profile:' + route.params.profileid);
API.getPosts(route.params.profileid).then((data) => { API.getPosts(route.params.profileid).then((data) => {
if(!subscribed) return 0;
setPosts(data); setPosts(data);
storeProfilePosts(route.params.profileid, data); storeProfilePosts(route.params.profileid, data);
console.log('Store Cache Profile:' + route.params.profileid); console.log('Store Cache Profile:' + route.params.profileid);
@@ -49,7 +55,12 @@ let Profile = ({ navigation, route }) => {
} else { } else {
navigation.navigate('Feed') navigation.navigate('Feed')
} }
}, [route.params]); }
getData();
return ()=>{
subscribed = false;
}
}, [route.params?.profileid]);
const renderPost = (({ item }) => { const renderPost = (({ item }) => {
if (item.nonOrganicType) if (item.nonOrganicType)
return (<></>); return (<></>);

View File

@@ -34,6 +34,7 @@ let LoginForm = () => {
onChangeText={text => setEmail(text)} onChangeText={text => setEmail(text)}
defaultValue={email} defaultValue={email}
placeholder="email" placeholder="email"
label="email:"
autoCapitalize='none' autoCapitalize='none'
autoComplete='email' autoComplete='email'
autoCorrect={false} autoCorrect={false}
@@ -45,6 +46,7 @@ let LoginForm = () => {
defaultValue={password} defaultValue={password}
placeholder="password" placeholder="password"
textContentType="password" textContentType="password"
label="password:"
secureTextEntry={true} secureTextEntry={true}
autoCapitalize='none' autoCapitalize='none'
autoComplete='email' autoComplete='email'
@@ -68,7 +70,7 @@ const styles = StyleSheet.create({
backgroundColor: 'white', backgroundColor: 'white',
flex: 1, flex: 1,
flexDirection: "column", flexDirection: "column",
justifyContent: "flex-start", justifyContent: "center",
padding: 15, padding: 15,
width: "100%", width: "100%",
alignContent: 'center', alignContent: 'center',

View File

@@ -44,13 +44,20 @@ let Media = (props) => {
const [videosFiles, setVideosFiles] = useState([]); const [videosFiles, setVideosFiles] = useState([]);
const [poster, setPoster] = useState(''); const [poster, setPoster] = useState('');
const [loaded, setLoaded] = useState(false); const [loaded, setLoaded] = useState(false);
useEffect(async () => { useEffect(() => {
let subscribed = true;
let getData = async () => {
if (!videosId[1]) return 0; if (!videosId[1]) return 0;
let videoObj = await API.getVideo(videosId[1]); let videoObj = await API.getVideo(videosId[1]);
if(videoObj && videoObj.files){ if(videoObj && videoObj.files && subscribed){
setVideosFiles(videoObj.files); setVideosFiles(videoObj.files);
setPoster(videoObj.pictures.sizes[4].link); setPoster(videoObj.pictures.sizes[4].link);
} }
};
getData();
return ()=>{
subscribed = false;
};
}, [props.content]) }, [props.content])
const video = videosFiles.length ? ( const video = videosFiles.length ? (
loaded ? <VideoPlayer videosFiles={videosFiles} poster={poster} videoId={videosId[1]} /> : loaded ? <VideoPlayer videosFiles={videosFiles} poster={poster} videoId={videosId[1]} /> :

View File

@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react'; import React, { useState } from 'react';
import { Text, ScrollView, FlatList, StyleSheet, View, Linking } from 'react-native'; import { Text, ScrollView, FlatList, StyleSheet, View } from 'react-native';
import Hyperlink from 'react-native-hyperlink' import Hyperlink from 'react-native-hyperlink'
import { Avatar, Button, Card, Title, Chip } from 'react-native-paper'; import { Button, Card, Chip } from 'react-native-paper';
import API from './../API.js'; import API from './../API.js';
import UserName from './UserName.js'; import UserName from './UserName.js';
import Media from './Media.js'; import Media from './Media.js';
@@ -58,7 +58,7 @@ let Post = (props) => {
return ( return (
<Card style={styles.card}> <Card style={styles.card}>
<Card.Content> <Card.Content>
<Hyperlink linkDefault={ true }> <Hyperlink linkDefault={ true } linkStyle={{}}>
{!post.nonOrganicType ? {!post.nonOrganicType ?
<View> <View>
<Text style={styles.userName}> <Text style={styles.userName}>
@@ -74,6 +74,7 @@ let Post = (props) => {
<View> <View>
<Chip icon="new-releases" style={{ width: 100 }} >News</Chip> <Chip icon="new-releases" style={{ width: 100 }} >News</Chip>
<Text style={{ fontSize: 18 }}>{cleanContent}</Text> <Text style={{ fontSize: 18 }}>{cleanContent}</Text>
<Media content={post.content} />
</View> </View>
} }
</Hyperlink> </Hyperlink>

View File

@@ -28,12 +28,21 @@ let UserName = ({ profileid, hideIcon }) => {
let [profile, setProfile] = useState({}); let [profile, setProfile] = useState({});
const navigation = useNavigation(); const navigation = useNavigation();
useEffect(async () => { useEffect(() => {
let subscribed = true;
let getData = async () => {
let cacheProfile = await getName(profileid); let cacheProfile = await getName(profileid);
if (cacheProfile && cacheProfile.profile) setProfile(cacheProfile); if (cacheProfile && cacheProfile.profile && subscribed) setProfile(cacheProfile);
let p = await API.getUserProfile(profileid).catch(() => { return {} }); let p = await API.getUserProfile(profileid).catch(() => { return {} });
if (subscribed)
setProfile(p); setProfile(p);
storeName(profileid, p) storeName(profileid, p);
console.log("Fetching Name:" + p?.profile?.firstName);
}
getData();
return () => {
subscribed = false;
};
}, [profileid]); }, [profileid]);
let icon = profile._id ? (!profile.isGroup ? "person-outline" : "group") : ''; let icon = profile._id ? (!profile.isGroup ? "person-outline" : "group") : '';

16507
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,34 +10,34 @@
"eject": "expo eject" "eject": "expo eject"
}, },
"dependencies": { "dependencies": {
"@react-native-async-storage/async-storage": "~1.15.0", "@react-native-async-storage/async-storage": "~1.17.3",
"@react-navigation/bottom-tabs": "^6.2.0", "@react-navigation/bottom-tabs": "^6.2.0",
"@react-navigation/material-bottom-tabs": "^6.1.1", "@react-navigation/material-bottom-tabs": "^6.1.1",
"@react-navigation/native": "^6.0.8", "@react-navigation/native": "^6.0.8",
"@react-navigation/native-stack": "^6.5.0", "@react-navigation/native-stack": "^6.5.0",
"expo": "~43.0.2", "expo": "^46.0.0",
"expo-av": "~10.1.3", "expo-av": "~12.0.4",
"expo-device": "~4.0.3", "expo-device": "~4.3.0",
"expo-notifications": "~0.13.3", "expo-notifications": "~0.16.1",
"expo-status-bar": "~1.1.0", "expo-status-bar": "~1.4.0",
"expo-updates": "~0.10.15", "expo-updates": "~0.14.7",
"moment": "^2.29.1", "moment": "^2.29.1",
"react": "17.0.1", "react": "18.0.0",
"react-dom": "17.0.1", "react-dom": "18.0.0",
"react-google-material-icons": "^1.0.4", "react-google-material-icons": "^1.0.4",
"react-native": "0.64.3", "react-native": "0.69.6",
"react-native-autoheight-webview": "^1.6.1", "react-native-autoheight-webview": "^1.6.1",
"react-native-hyperlink": "0.0.19", "react-native-hyperlink": "0.0.19",
"react-native-paper": "^4.11.2", "react-native-paper": "^4.11.2",
"react-native-safe-area-context": "3.3.2", "react-native-safe-area-context": "4.3.1",
"react-native-screens": "~3.8.0", "react-native-screens": "~3.15.0",
"react-native-vector-icons": "^9.1.0", "react-native-vector-icons": "^9.1.0",
"react-native-web": "0.17.1", "react-native-web": "~0.18.7",
"react-native-webview": "11.13.0", "react-native-webview": "11.23.0",
"valtio": "^1.4.0" "valtio": "^1.4.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.12.9" "@babel/core": "^7.18.6"
}, },
"private": true "private": true
} }