Valtio and new tab menu

This commit is contained in:
aeroreyna
2022-03-24 22:00:00 -07:00
parent 0bee9204f2
commit 296c153b47
13 changed files with 93 additions and 66 deletions

4
API.js
View File

@@ -59,7 +59,7 @@ let getProfileFromCache = async (id, refresh=false) => {
return userNameCache[id]; return userNameCache[id];
if (working_on[id] && !refresh) if (working_on[id] && !refresh)
return working_on[id]; return working_on[id];
console.log(id, "not in cache, getting...") //console.log(id, "not in cache, getting...")
working_on[id] = getCall("/user/" + id) working_on[id] = getCall("/user/" + id)
return working_on[id]; return working_on[id];
} }
@@ -67,7 +67,7 @@ let getProfileFromCache = async (id, refresh=false) => {
const API = { const API = {
isLoggedIn: async () => { isLoggedIn: async () => {
return getCall().then((data) => { return getCall().then((data) => {
console.log("isLoggedIn", data) //console.log("isLoggedIn", data)
if (data && data.status && data.status === 'ok') { if (data && data.status && data.status === 'ok') {
CurrentUserId = data.userInfo._id; CurrentUserId = data.userInfo._id;
CurrentProfile = data.profileInfo._id; CurrentProfile = data.profileInfo._id;

19
App.js
View File

@@ -3,6 +3,7 @@ import React, { useState, useRef, useEffect } from 'react';
import { NavigationContainer } from '@react-navigation/native'; import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs'; import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Provider as PaperProvider, DefaultTheme, } from 'react-native-paper'; import { Provider as PaperProvider, DefaultTheme, } from 'react-native-paper';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import Login from "./Views/Login.js" import Login from "./Views/Login.js"
@@ -18,7 +19,7 @@ import * as Notifications from 'expo-notifications';
import API from './API.js'; import API from './API.js';
const Tab = createMaterialBottomTabNavigator(); const Tab = createBottomTabNavigator();
const Stack = createNativeStackNavigator(); const Stack = createNativeStackNavigator();
const theme = { const theme = {
...DefaultTheme, ...DefaultTheme,
@@ -106,7 +107,8 @@ const MainNavigation = () => {
<Tab.Navigator initialRouteName="Home" <Tab.Navigator initialRouteName="Home"
activeColor="#0d6efd" activeColor="#0d6efd"
inactiveColor="#FFFFFF" inactiveColor="#FFFFFF"
barStyle={{ backgroundColor: '#000000' }}> barStyle={{ backgroundColor: '#000000' }}
>
<Tab.Screen <Tab.Screen
name="Feed" name="Feed"
component={Feed} component={Feed}
@@ -115,13 +117,14 @@ const MainNavigation = () => {
tabBarIcon: ({ color }) => ( tabBarIcon: ({ color }) => (
<MaterialIcons name="home" color={color} size={26} /> <MaterialIcons name="home" color={color} size={26} />
), ),
tabBarBadge: false header: ()=>{<></>},
}} }}
listeners={({ navigation, route }) => ({ listeners={({ navigation, route }) => ({
tabPress: e => { tabPress: e => {
navigation.navigate('Feed') navigation.navigate('Feed')
}, },
})} })}
/> />
<Tab.Screen <Tab.Screen
name="Notifications" name="Notifications"
@@ -131,7 +134,7 @@ const MainNavigation = () => {
tabBarIcon: ({ color }) => ( tabBarIcon: ({ color }) => (
<MaterialIcons name="notifications" color={color} size={26} /> <MaterialIcons name="notifications" color={color} size={26} />
), ),
tabBarBadge: false header: ()=>{<></>},
}} }}
/> />
<Tab.Screen <Tab.Screen
@@ -142,7 +145,7 @@ const MainNavigation = () => {
tabBarIcon: ({ color }) => ( tabBarIcon: ({ color }) => (
<MaterialIcons name="search" color={color} size={26} /> <MaterialIcons name="search" color={color} size={26} />
), ),
tabBarBadge: false header: ()=>{<></>},
}} }}
/> />
<Tab.Screen <Tab.Screen
@@ -153,7 +156,7 @@ const MainNavigation = () => {
tabBarIcon: ({ color }) => ( tabBarIcon: ({ color }) => (
<MaterialIcons name="groups" color={color} size={26} /> <MaterialIcons name="groups" color={color} size={26} />
), ),
tabBarBadge: false header: ()=>{<></>},
}} }}
/> />
<Tab.Screen <Tab.Screen
@@ -164,7 +167,7 @@ const MainNavigation = () => {
tabBarIcon: ({ color }) => ( tabBarIcon: ({ color }) => (
<MaterialIcons name="subscriptions" color={color} size={26} /> <MaterialIcons name="subscriptions" color={color} size={26} />
), ),
tabBarBadge: false header: ()=>{<></>},
}} }}
/> />
@@ -176,7 +179,7 @@ const MainNavigation = () => {
tabBarIcon: ({ color }) => ( tabBarIcon: ({ color }) => (
<MaterialIcons name="logout" color={color} size={26} /> <MaterialIcons name="logout" color={color} size={26} />
), ),
tabBarBadge: false header: ()=>{<></>},
}} }}
/> />
</Tab.Navigator> </Tab.Navigator>

View File

@@ -4,6 +4,8 @@ import { ScrollView, ActivityIndicator, StyleSheet, SafeAreaView, FlatList } fro
import { Title } from 'react-native-paper'; import { Title } from 'react-native-paper';
import API from "../API"; import API from "../API";
import CourseCard from "../components/CourseCard"; import CourseCard from "../components/CourseCard";
import { useSnapshot } from 'valtio';
import GlobalState from '../contexts/GlobalState.js';
const getCourses = async (profileObj) => { const getCourses = async (profileObj) => {
@@ -48,7 +50,8 @@ const getCourses = async (profileObj) => {
} }
const Courses = () => { const Courses = () => {
const [Me, setMeProfile] = React.useState({}); const gState = useSnapshot(GlobalState);
const viewer = gState.me;
const [searchQuery, setSearchQuery] = React.useState(''); const [searchQuery, setSearchQuery] = React.useState('');
const [groups, setGroups] = React.useState([]); const [groups, setGroups] = React.useState([]);
const [popular, setPopular] = React.useState([]); const [popular, setPopular] = React.useState([]);
@@ -56,12 +59,7 @@ const Courses = () => {
const [queryTimer, setQueryTimer] = React.useState(0); const [queryTimer, setQueryTimer] = React.useState(0);
useEffect(async () => { useEffect(async () => {
let Me = await API.getMe(); let r = await getCourses(viewer);
setMeProfile(Me);
//API.getCourses('').then((data) => {
// setGroups(data.groups || []);
//});
let r = await getCourses(Me);
setGroups(r.courses || []); setGroups(r.courses || []);
setPopular(r.popular || []); setPopular(r.popular || []);
setWatching(r.watching || []); setWatching(r.watching || []);

View File

@@ -4,6 +4,8 @@ import { View, ActivityIndicator, StyleSheet, SafeAreaView, FlatList } from 'rea
import API from './../API.js'; 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 { useSnapshot } from 'valtio';
import GlobalState from '../contexts/GlobalState.js';
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
@@ -27,27 +29,30 @@ const getFeed = async () => {
} }
let Feed = ({ navigation, route }) => { let Feed = ({ navigation, route }) => {
let [Me, setMeProfile] = useState({});
let [Posts, setPosts] = useState([]); let [Posts, setPosts] = useState([]);
console.log("Render Feed");
useEffect(async () => { useEffect(async () => {
let loggedIn = await API.isLoggedIn(); let loggedIn = await API.isLoggedIn();
if(!loggedIn) return navigation.navigate('Login'); if(!loggedIn) return navigation.navigate('Login');
let cacheFeed = await getFeed() || [];
setPosts(cacheFeed);
let r = await API.getMe();
setMeProfile(r);
if (route.params && route.params.profileid) { if (route.params && route.params.profileid) {
navigation.navigate('Profile', { profileid: route.params.profileid }) navigation.navigate('Profile', { profileid: route.params.profileid })
} else {
let posts = await API.getPosts();
setPosts(posts);
storeFeed(posts);
} }
API.getMe().then((me) => {
GlobalState.me = me;
});
console.log("Feed from cache")
let cacheFeed = await getFeed() || [];
if(cacheFeed.length) setPosts(cacheFeed);
console.log("Feed from server")
let posts = await API.getPosts();
setPosts(posts);
storeFeed(posts);
console.log("Feed, end useEffect")
}, [route.params]); }, [route.params]);
const renderPost = (({ item }) => { const renderPost = (({ item }) => {
if (item.nonOrganicType === 'PopularUsers' || item.nonOrganicType === 'PopularGroups') if (item.nonOrganicType === 'PopularUsers' || item.nonOrganicType === 'PopularGroups')
return (<></>); return (<></>);
return (<Post post={item} viewer={Me} />); return (<Post post={item} />);
}); });

View File

@@ -5,18 +5,15 @@ import { Card } from 'react-native-paper';
import API from '../API.js'; import API from '../API.js';
import Post from '../components/Post.js'; import Post from '../components/Post.js';
import Moment from 'moment'; import Moment from 'moment';
import { useSnapshot } from 'valtio';
import GlobalState from '../contexts/GlobalState.js';
let NotificationsView = ({ navigation, route }) => { let NotificationsView = ({ navigation, route }) => {
let [Me, setMeProfile] = useState({}); const gState = useSnapshot(GlobalState);
let [notifications, setNotifications] = useState([]); const viewer = gState.me;
useEffect(async () => {
let r = await API.getMe();
setMeProfile(r);
setNotifications(r.notifications)
}, [route.params]);
const renderNotification = (({ item }) => { const renderNotification = (({ item }) => {
const gotToPost = () => { const gotToPost = () => {
navigation.navigate('SinglePost', { postid: item.postid, viewer: Me }); navigation.navigate('SinglePost', { postid: item.postid });
}; };
return ( return (
<Card style={{ margin: 3 }} onPress={gotToPost}> <Card style={{ margin: 3 }} onPress={gotToPost}>
@@ -35,7 +32,7 @@ let NotificationsView = ({ navigation, route }) => {
<SafeAreaView style={styles.container}> <SafeAreaView style={styles.container}>
<View> <View>
<FlatList <FlatList
data={notifications.reverse().slice(0, 10)} data={[...viewer.notifications].reverse().slice(0, 10)}
renderItem={renderNotification} renderItem={renderNotification}
keyExtractor={item => item.ts} keyExtractor={item => item.ts}
/> />

View File

@@ -27,14 +27,11 @@ const getProfilePosts = async (profileid) => {
} }
let Profile = ({ navigation, route }) => { let Profile = ({ navigation, route }) => {
let [Me, setMeProfile] = useState({});
let [Posts, setPosts] = useState([]); let [Posts, setPosts] = useState([]);
let [profile, setProfile] = useState({}); let [profile, setProfile] = useState({});
useEffect(async () => { useEffect(async () => {
setPosts([]); setPosts([]);
let r = await API.getMe();
setMeProfile(r);
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); getProfilePosts(route.params.profileid).then(setPosts);
@@ -56,7 +53,7 @@ let Profile = ({ navigation, route }) => {
const renderPost = (({ item }) => { const renderPost = (({ item }) => {
if (item.nonOrganicType) if (item.nonOrganicType)
return (<></>); return (<></>);
return (<Post post={item} viewer={Me} />); return (<Post post={item} />);
}); });
const header = ( const header = (
<View> <View>

View File

@@ -13,7 +13,7 @@ let SinglePost = ({ route }) => {
}, [route]); }, [route]);
return (post._id ? ( return (post._id ? (
<ScrollView> <ScrollView>
<Post post={post} viewer={route.params.viewer} /> <Post post={post}/>
</ScrollView> </ScrollView>
) : null); ) : null);
}; };

View File

@@ -3,11 +3,13 @@ import { Text, View, ScrollView, StyleSheet } from 'react-native';
import { FAB, Button, Card, Title, IconButton } from 'react-native-paper'; import { FAB, Button, Card, Title, IconButton } 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 { useSnapshot } from 'valtio';
import AwesomeIcon from 'react-native-vector-icons/FontAwesome'; import GlobalState from '../contexts/GlobalState.js';
let Comment = ({ comment, postid, viewer }) => { let Comment = ({ comment, postid }) => {
const gState = useSnapshot(GlobalState);
const viewer = gState.me;
let [likes, changeLikes] = useState(Object.keys(comment.reactions).length); let [likes, changeLikes] = useState(Object.keys(comment.reactions).length);
const newCommentReaction = () => { const newCommentReaction = () => {
if (!comment.reactions[viewer._id]) { if (!comment.reactions[viewer._id]) {

View File

@@ -8,9 +8,12 @@ import Media from './Media.js';
import Comment from "./Comment"; import Comment from "./Comment";
import NewComment from './NewComment.js'; import NewComment from './NewComment.js';
import Moment from 'moment'; import Moment from 'moment';
import { useSnapshot } from 'valtio';
import GlobalState from '../contexts/GlobalState.js';
let Post = (props) => { let Post = (props) => {
const viewer = props.viewer; const gState = useSnapshot(GlobalState);
const viewer = gState.me;
let [showCommentsB, changeshowCommentsB] = useState(false); let [showCommentsB, changeshowCommentsB] = useState(false);
let [post, changePost] = useState(props.post); let [post, changePost] = useState(props.post);
let [likes, changeLikes] = useState(Object.keys(post.reactions).length); let [likes, changeLikes] = useState(Object.keys(post.reactions).length);
@@ -50,7 +53,7 @@ let Post = (props) => {
} }
} }
const renderComment = ({ item }) => ( const renderComment = ({ item }) => (
<Comment comment={item} viewer={viewer} postid={post._id} /> <Comment comment={item} postid={post._id} />
); );
return ( return (
<Card style={styles.card}> <Card style={styles.card}>

View File

@@ -2,38 +2,27 @@ import * as React from 'react';
import { View, StyleSheet, Button } from 'react-native'; import { View, StyleSheet, Button } from 'react-native';
import { Video, AVPlaybackStatus } from 'expo-av'; import { Video, AVPlaybackStatus } from 'expo-av';
import API from '../API'; import API from '../API';
import { useSnapshot } from 'valtio';
import GlobalState from '../contexts/GlobalState.js';
const VideoPlayer = ({ videosFiles, videoId }) => { const VideoPlayer = ({ videosFiles, videoId }) => {
//console.log(videosFiles) const gState = useSnapshot(GlobalState);
let chosenVideo = []; //rendition const viewer = gState.me;
let chosenVideo = [];
videosFiles.forEach((f) => { videosFiles.forEach((f) => {
if (f.rendition === 'adaptive') chosenVideo.push(f); if (f.rendition === 'adaptive') chosenVideo.push(f);
}); });
const video = React.useRef(null); const video = React.useRef(null);
const [status, setStatus] = React.useState({}); const [status, setStatus] = React.useState({});
const [Me, setMeProfile] = React.useState({});
React.useEffect( async ()=>{ React.useEffect( async ()=>{
await API.getMe().then(setMeProfile);
setTimeout(()=>{ setTimeout(()=>{
if(Me.data && Me.data[videoId]){ if(viewer.data && viewer.data[videoId]){
//video.setPositionAsync(Me.data[videoId].time*1000); video.current.setPositionAsync(viewer.data[videoId].time*1000);
//status.positionMillis = Me.data[videoId].time*1000;
//setStatus({...status});
video.current.setPositionAsync(Me.data[videoId].time*1000);
} }
}, 5000);
//status.isPlaying = true;
//playAsync();
}, 5000)
}, []) }, [])
console.log(status)
//console.log(status)
return ( return (
<Video <Video
ref={video} ref={video}

8
contexts/GlobalState.js Normal file
View File

@@ -0,0 +1,8 @@
import { proxy, useSnapshot } from 'valtio';
const GlobalState = proxy({
me: {},
profiles: {},
});
export default GlobalState;

23
package-lock.json generated
View File

@@ -2124,6 +2124,16 @@
"resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-1.0.0.tgz", "resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-1.0.0.tgz",
"integrity": "sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w==" "integrity": "sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w=="
}, },
"@react-navigation/bottom-tabs": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.2.0.tgz",
"integrity": "sha512-MNwXbybjapRFZJtO+fNu5YuTYQGzzYAUIF4IsY2+ZBXoCRpzuDq8gXV7ChKDJaaTeX39IoDUng3qGXbvtVcivA==",
"requires": {
"@react-navigation/elements": "^1.3.1",
"color": "^3.1.3",
"warn-once": "^0.1.0"
}
},
"@react-navigation/core": { "@react-navigation/core": {
"version": "6.1.1", "version": "6.1.1",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.1.1.tgz", "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.1.1.tgz",
@@ -6813,6 +6823,11 @@
} }
} }
}, },
"proxy-compare": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.1.0.tgz",
"integrity": "sha512-wapJ3h/w8fRSyPEG0y2WMV+tf9xwvj3nxM6aHVuPEOwKs/t5xLSKZb44ubNTiqq2T6lmEMHEWGMTaU2L6ddaFA=="
},
"pump": { "pump": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -8528,6 +8543,14 @@
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
}, },
"valtio": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/valtio/-/valtio-1.4.0.tgz",
"integrity": "sha512-mKFSkBwHjmspIfaoLwAElSZvNC0A6eRbA7iM7Tx8kIxnrLYBIaaOMcztdIPLVrG4QHUQov0XwmoxeJIvqKFoWA==",
"requires": {
"proxy-compare": "2.1.0"
}
},
"vary": { "vary": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",

View File

@@ -11,6 +11,7 @@
}, },
"dependencies": { "dependencies": {
"@react-native-async-storage/async-storage": "~1.15.0", "@react-native-async-storage/async-storage": "~1.15.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",
@@ -32,7 +33,8 @@
"react-native-screens": "^3.13.1", "react-native-screens": "^3.13.1",
"react-native-vector-icons": "^9.1.0", "react-native-vector-icons": "^9.1.0",
"react-native-web": "0.17.1", "react-native-web": "0.17.1",
"react-native-webview": "^11.17.2" "react-native-webview": "^11.17.2",
"valtio": "^1.4.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.12.9" "@babel/core": "^7.12.9"