Valtio and new tab menu
This commit is contained in:
4
API.js
4
API.js
@@ -59,7 +59,7 @@ let getProfileFromCache = async (id, refresh=false) => {
|
||||
return userNameCache[id];
|
||||
if (working_on[id] && !refresh)
|
||||
return working_on[id];
|
||||
console.log(id, "not in cache, getting...")
|
||||
//console.log(id, "not in cache, getting...")
|
||||
working_on[id] = getCall("/user/" + id)
|
||||
return working_on[id];
|
||||
}
|
||||
@@ -67,7 +67,7 @@ let getProfileFromCache = async (id, refresh=false) => {
|
||||
const API = {
|
||||
isLoggedIn: async () => {
|
||||
return getCall().then((data) => {
|
||||
console.log("isLoggedIn", data)
|
||||
//console.log("isLoggedIn", data)
|
||||
if (data && data.status && data.status === 'ok') {
|
||||
CurrentUserId = data.userInfo._id;
|
||||
CurrentProfile = data.profileInfo._id;
|
||||
|
||||
19
App.js
19
App.js
@@ -3,6 +3,7 @@ import React, { useState, useRef, useEffect } from 'react';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
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 MaterialIcons from 'react-native-vector-icons/MaterialIcons';
|
||||
import Login from "./Views/Login.js"
|
||||
@@ -18,7 +19,7 @@ import * as Notifications from 'expo-notifications';
|
||||
import API from './API.js';
|
||||
|
||||
|
||||
const Tab = createMaterialBottomTabNavigator();
|
||||
const Tab = createBottomTabNavigator();
|
||||
const Stack = createNativeStackNavigator();
|
||||
const theme = {
|
||||
...DefaultTheme,
|
||||
@@ -106,7 +107,8 @@ const MainNavigation = () => {
|
||||
<Tab.Navigator initialRouteName="Home"
|
||||
activeColor="#0d6efd"
|
||||
inactiveColor="#FFFFFF"
|
||||
barStyle={{ backgroundColor: '#000000' }}>
|
||||
barStyle={{ backgroundColor: '#000000' }}
|
||||
>
|
||||
<Tab.Screen
|
||||
name="Feed"
|
||||
component={Feed}
|
||||
@@ -115,13 +117,14 @@ const MainNavigation = () => {
|
||||
tabBarIcon: ({ color }) => (
|
||||
<MaterialIcons name="home" color={color} size={26} />
|
||||
),
|
||||
tabBarBadge: false
|
||||
header: ()=>{<></>},
|
||||
}}
|
||||
listeners={({ navigation, route }) => ({
|
||||
tabPress: e => {
|
||||
navigation.navigate('Feed')
|
||||
},
|
||||
})}
|
||||
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="Notifications"
|
||||
@@ -131,7 +134,7 @@ const MainNavigation = () => {
|
||||
tabBarIcon: ({ color }) => (
|
||||
<MaterialIcons name="notifications" color={color} size={26} />
|
||||
),
|
||||
tabBarBadge: false
|
||||
header: ()=>{<></>},
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
@@ -142,7 +145,7 @@ const MainNavigation = () => {
|
||||
tabBarIcon: ({ color }) => (
|
||||
<MaterialIcons name="search" color={color} size={26} />
|
||||
),
|
||||
tabBarBadge: false
|
||||
header: ()=>{<></>},
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
@@ -153,7 +156,7 @@ const MainNavigation = () => {
|
||||
tabBarIcon: ({ color }) => (
|
||||
<MaterialIcons name="groups" color={color} size={26} />
|
||||
),
|
||||
tabBarBadge: false
|
||||
header: ()=>{<></>},
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
@@ -164,7 +167,7 @@ const MainNavigation = () => {
|
||||
tabBarIcon: ({ color }) => (
|
||||
<MaterialIcons name="subscriptions" color={color} size={26} />
|
||||
),
|
||||
tabBarBadge: false
|
||||
header: ()=>{<></>},
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -176,7 +179,7 @@ const MainNavigation = () => {
|
||||
tabBarIcon: ({ color }) => (
|
||||
<MaterialIcons name="logout" color={color} size={26} />
|
||||
),
|
||||
tabBarBadge: false
|
||||
header: ()=>{<></>},
|
||||
}}
|
||||
/>
|
||||
</Tab.Navigator>
|
||||
|
||||
@@ -4,6 +4,8 @@ import { ScrollView, ActivityIndicator, StyleSheet, SafeAreaView, FlatList } fro
|
||||
import { Title } from 'react-native-paper';
|
||||
import API from "../API";
|
||||
import CourseCard from "../components/CourseCard";
|
||||
import { useSnapshot } from 'valtio';
|
||||
import GlobalState from '../contexts/GlobalState.js';
|
||||
|
||||
|
||||
const getCourses = async (profileObj) => {
|
||||
@@ -48,7 +50,8 @@ const getCourses = async (profileObj) => {
|
||||
}
|
||||
|
||||
const Courses = () => {
|
||||
const [Me, setMeProfile] = React.useState({});
|
||||
const gState = useSnapshot(GlobalState);
|
||||
const viewer = gState.me;
|
||||
const [searchQuery, setSearchQuery] = React.useState('');
|
||||
const [groups, setGroups] = React.useState([]);
|
||||
const [popular, setPopular] = React.useState([]);
|
||||
@@ -56,12 +59,7 @@ const Courses = () => {
|
||||
const [queryTimer, setQueryTimer] = React.useState(0);
|
||||
|
||||
useEffect(async () => {
|
||||
let Me = await API.getMe();
|
||||
setMeProfile(Me);
|
||||
//API.getCourses('').then((data) => {
|
||||
// setGroups(data.groups || []);
|
||||
//});
|
||||
let r = await getCourses(Me);
|
||||
let r = await getCourses(viewer);
|
||||
setGroups(r.courses || []);
|
||||
setPopular(r.popular || []);
|
||||
setWatching(r.watching || []);
|
||||
|
||||
@@ -4,6 +4,8 @@ import { View, ActivityIndicator, StyleSheet, SafeAreaView, FlatList } from 'rea
|
||||
import API from './../API.js';
|
||||
import Post from './../components/Post.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';
|
||||
|
||||
@@ -27,27 +29,30 @@ const getFeed = async () => {
|
||||
}
|
||||
|
||||
let Feed = ({ navigation, route }) => {
|
||||
let [Me, setMeProfile] = useState({});
|
||||
let [Posts, setPosts] = useState([]);
|
||||
console.log("Render Feed");
|
||||
useEffect(async () => {
|
||||
let loggedIn = await API.isLoggedIn();
|
||||
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) {
|
||||
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]);
|
||||
const renderPost = (({ item }) => {
|
||||
if (item.nonOrganicType === 'PopularUsers' || item.nonOrganicType === 'PopularGroups')
|
||||
return (<></>);
|
||||
return (<Post post={item} viewer={Me} />);
|
||||
return (<Post post={item} />);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -5,18 +5,15 @@ import { Card } from 'react-native-paper';
|
||||
import API from '../API.js';
|
||||
import Post from '../components/Post.js';
|
||||
import Moment from 'moment';
|
||||
import { useSnapshot } from 'valtio';
|
||||
import GlobalState from '../contexts/GlobalState.js';
|
||||
|
||||
let NotificationsView = ({ navigation, route }) => {
|
||||
let [Me, setMeProfile] = useState({});
|
||||
let [notifications, setNotifications] = useState([]);
|
||||
useEffect(async () => {
|
||||
let r = await API.getMe();
|
||||
setMeProfile(r);
|
||||
setNotifications(r.notifications)
|
||||
}, [route.params]);
|
||||
const gState = useSnapshot(GlobalState);
|
||||
const viewer = gState.me;
|
||||
const renderNotification = (({ item }) => {
|
||||
const gotToPost = () => {
|
||||
navigation.navigate('SinglePost', { postid: item.postid, viewer: Me });
|
||||
navigation.navigate('SinglePost', { postid: item.postid });
|
||||
};
|
||||
return (
|
||||
<Card style={{ margin: 3 }} onPress={gotToPost}>
|
||||
@@ -35,7 +32,7 @@ let NotificationsView = ({ navigation, route }) => {
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View>
|
||||
<FlatList
|
||||
data={notifications.reverse().slice(0, 10)}
|
||||
data={[...viewer.notifications].reverse().slice(0, 10)}
|
||||
renderItem={renderNotification}
|
||||
keyExtractor={item => item.ts}
|
||||
/>
|
||||
|
||||
@@ -27,14 +27,11 @@ const getProfilePosts = async (profileid) => {
|
||||
}
|
||||
|
||||
let Profile = ({ navigation, route }) => {
|
||||
let [Me, setMeProfile] = useState({});
|
||||
let [Posts, setPosts] = useState([]);
|
||||
let [profile, setProfile] = useState({});
|
||||
|
||||
useEffect(async () => {
|
||||
setPosts([]);
|
||||
let r = await API.getMe();
|
||||
setMeProfile(r);
|
||||
if (route.params && route.params.profileid) {
|
||||
console.log('Loading Cache Profile:' + route.params.profileid);
|
||||
getProfilePosts(route.params.profileid).then(setPosts);
|
||||
@@ -56,7 +53,7 @@ let Profile = ({ navigation, route }) => {
|
||||
const renderPost = (({ item }) => {
|
||||
if (item.nonOrganicType)
|
||||
return (<></>);
|
||||
return (<Post post={item} viewer={Me} />);
|
||||
return (<Post post={item} />);
|
||||
});
|
||||
const header = (
|
||||
<View>
|
||||
|
||||
@@ -13,7 +13,7 @@ let SinglePost = ({ route }) => {
|
||||
}, [route]);
|
||||
return (post._id ? (
|
||||
<ScrollView>
|
||||
<Post post={post} viewer={route.params.viewer} />
|
||||
<Post post={post}/>
|
||||
</ScrollView>
|
||||
) : null);
|
||||
};
|
||||
|
||||
@@ -3,11 +3,13 @@ import { Text, View, ScrollView, StyleSheet } from 'react-native';
|
||||
import { FAB, Button, Card, Title, IconButton } from 'react-native-paper';
|
||||
import API from './../API.js';
|
||||
import UserName from './UserName.js';
|
||||
import Media from './Media.js';
|
||||
import AwesomeIcon from 'react-native-vector-icons/FontAwesome';
|
||||
import { useSnapshot } from 'valtio';
|
||||
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);
|
||||
const newCommentReaction = () => {
|
||||
if (!comment.reactions[viewer._id]) {
|
||||
|
||||
@@ -8,9 +8,12 @@ import Media from './Media.js';
|
||||
import Comment from "./Comment";
|
||||
import NewComment from './NewComment.js';
|
||||
import Moment from 'moment';
|
||||
import { useSnapshot } from 'valtio';
|
||||
import GlobalState from '../contexts/GlobalState.js';
|
||||
|
||||
let Post = (props) => {
|
||||
const viewer = props.viewer;
|
||||
const gState = useSnapshot(GlobalState);
|
||||
const viewer = gState.me;
|
||||
let [showCommentsB, changeshowCommentsB] = useState(false);
|
||||
let [post, changePost] = useState(props.post);
|
||||
let [likes, changeLikes] = useState(Object.keys(post.reactions).length);
|
||||
@@ -50,7 +53,7 @@ let Post = (props) => {
|
||||
}
|
||||
}
|
||||
const renderComment = ({ item }) => (
|
||||
<Comment comment={item} viewer={viewer} postid={post._id} />
|
||||
<Comment comment={item} postid={post._id} />
|
||||
);
|
||||
return (
|
||||
<Card style={styles.card}>
|
||||
|
||||
@@ -2,38 +2,27 @@ import * as React from 'react';
|
||||
import { View, StyleSheet, Button } from 'react-native';
|
||||
import { Video, AVPlaybackStatus } from 'expo-av';
|
||||
import API from '../API';
|
||||
import { useSnapshot } from 'valtio';
|
||||
import GlobalState from '../contexts/GlobalState.js';
|
||||
|
||||
const VideoPlayer = ({ videosFiles, videoId }) => {
|
||||
//console.log(videosFiles)
|
||||
let chosenVideo = []; //rendition
|
||||
const gState = useSnapshot(GlobalState);
|
||||
const viewer = gState.me;
|
||||
let chosenVideo = [];
|
||||
videosFiles.forEach((f) => {
|
||||
if (f.rendition === 'adaptive') chosenVideo.push(f);
|
||||
});
|
||||
const video = React.useRef(null);
|
||||
const [status, setStatus] = React.useState({});
|
||||
const [Me, setMeProfile] = React.useState({});
|
||||
|
||||
React.useEffect( async ()=>{
|
||||
await API.getMe().then(setMeProfile);
|
||||
setTimeout(()=>{
|
||||
if(Me.data && Me.data[videoId]){
|
||||
//video.setPositionAsync(Me.data[videoId].time*1000);
|
||||
//status.positionMillis = Me.data[videoId].time*1000;
|
||||
//setStatus({...status});
|
||||
video.current.setPositionAsync(Me.data[videoId].time*1000);
|
||||
if(viewer.data && viewer.data[videoId]){
|
||||
video.current.setPositionAsync(viewer.data[videoId].time*1000);
|
||||
}
|
||||
|
||||
//status.isPlaying = true;
|
||||
|
||||
//playAsync();
|
||||
|
||||
}, 5000)
|
||||
}, 5000);
|
||||
}, [])
|
||||
|
||||
console.log(status)
|
||||
|
||||
//console.log(status)
|
||||
|
||||
return (
|
||||
<Video
|
||||
ref={video}
|
||||
|
||||
8
contexts/GlobalState.js
Normal file
8
contexts/GlobalState.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import { proxy, useSnapshot } from 'valtio';
|
||||
|
||||
const GlobalState = proxy({
|
||||
me: {},
|
||||
profiles: {},
|
||||
});
|
||||
|
||||
export default GlobalState;
|
||||
23
package-lock.json
generated
23
package-lock.json
generated
@@ -2124,6 +2124,16 @@
|
||||
"resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-1.0.0.tgz",
|
||||
"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": {
|
||||
"version": "6.1.1",
|
||||
"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": {
|
||||
"version": "3.0.0",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@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/native": "^6.0.8",
|
||||
"@react-navigation/native-stack": "^6.5.0",
|
||||
@@ -32,7 +33,8 @@
|
||||
"react-native-screens": "^3.13.1",
|
||||
"react-native-vector-icons": "^9.1.0",
|
||||
"react-native-web": "0.17.1",
|
||||
"react-native-webview": "^11.17.2"
|
||||
"react-native-webview": "^11.17.2",
|
||||
"valtio": "^1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.9"
|
||||
|
||||
Reference in New Issue
Block a user