Update on feed button, new groups UI search and round borders
This commit is contained in:
9
App.js
9
App.js
@@ -25,6 +25,7 @@ import InviteView from './Views/Invite.js';
|
|||||||
import MediaView from './components/MediaView.js';
|
import MediaView from './components/MediaView.js';
|
||||||
import { useSnapshot } from 'valtio';
|
import { useSnapshot } from 'valtio';
|
||||||
import GlobalState from './contexts/GlobalState.js';
|
import GlobalState from './contexts/GlobalState.js';
|
||||||
|
import NewGroup from './Views/NewGroup.js';
|
||||||
|
|
||||||
|
|
||||||
const Tab = createBottomTabNavigator();
|
const Tab = createBottomTabNavigator();
|
||||||
@@ -148,7 +149,7 @@ const MainNavigation = () => {
|
|||||||
}}
|
}}
|
||||||
listeners={({ navigation, route }) => ({
|
listeners={({ navigation, route }) => ({
|
||||||
tabPress: e => {
|
tabPress: e => {
|
||||||
navigation.navigate('Feed')
|
navigation.navigate('Feed', {reRender: Math.random()});
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
|
|
||||||
@@ -247,7 +248,7 @@ export default function App() {
|
|||||||
<Appbar.Header style={{backgroundColor: '#fff'}}>
|
<Appbar.Header style={{backgroundColor: '#fff'}}>
|
||||||
{props.navigation.canGoBack() ? <Appbar.BackAction onPress={()=>{
|
{props.navigation.canGoBack() ? <Appbar.BackAction onPress={()=>{
|
||||||
props.navigation.goBack();
|
props.navigation.goBack();
|
||||||
}} /> : <></>}
|
}} /> : <Appbar.Action icon="menu" style={{padding:0, margin:0}} onPress={()=>{props.navigation.navigate('Menu');}} />}
|
||||||
<Appbar.Content title="EMI Fellowship" titleStyle={{}}/>
|
<Appbar.Content title="EMI Fellowship" titleStyle={{}}/>
|
||||||
<Appbar.Action icon="chat" onPress={()=>{alert("Chats are comming soon.")}} />
|
<Appbar.Action icon="chat" onPress={()=>{alert("Chats are comming soon.")}} />
|
||||||
<Appbar.Action icon="search" onPress={()=>{props.navigation.navigate("Search")}} />
|
<Appbar.Action icon="search" onPress={()=>{props.navigation.navigate("Search")}} />
|
||||||
@@ -268,6 +269,10 @@ export default function App() {
|
|||||||
name="NewPost"
|
name="NewPost"
|
||||||
component={NewPostView}
|
component={NewPostView}
|
||||||
/>
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="NewGroup"
|
||||||
|
component={NewGroup}
|
||||||
|
/>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="Search"
|
name="Search"
|
||||||
component={Search}
|
component={Search}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ const getFeed = async () => {
|
|||||||
|
|
||||||
let Feed = ({ navigation, route }) => {
|
let Feed = ({ navigation, route }) => {
|
||||||
let [Posts, setPosts] = useState([]);
|
let [Posts, setPosts] = useState([]);
|
||||||
|
const flatListRef = React.useRef()
|
||||||
console.log("Render Feed");
|
console.log("Render Feed");
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let subscribed = true;
|
let subscribed = true;
|
||||||
@@ -39,15 +40,18 @@ let Feed = ({ navigation, route }) => {
|
|||||||
if (route.params && route.params.profileid) {
|
if (route.params && route.params.profileid) {
|
||||||
return navigation.navigate('Profile', { profileid: route.params.profileid })
|
return navigation.navigate('Profile', { profileid: route.params.profileid })
|
||||||
}
|
}
|
||||||
API.getMe().then((me) => {
|
if(!route.params?.reRender){
|
||||||
if (subscribed){
|
API.getMe().then((me) => {
|
||||||
GlobalState.me = me;
|
if (subscribed){
|
||||||
}
|
GlobalState.me = me;
|
||||||
});
|
}
|
||||||
console.log("Feed from cache")
|
});
|
||||||
let cacheFeed = await getFeed() || [];
|
console.log("Feed from cache")
|
||||||
if (cacheFeed.length && subscribed) setPosts(cacheFeed);
|
let cacheFeed = await getFeed() || [];
|
||||||
console.log("Feed from server")
|
if (cacheFeed.length && subscribed) setPosts(cacheFeed);
|
||||||
|
console.log("Feed from server")
|
||||||
|
}
|
||||||
|
flatListRef.current.scrollToOffset({ animated: true, offset: 0 })
|
||||||
let posts = await API.getPosts();
|
let posts = await API.getPosts();
|
||||||
if (subscribed) {
|
if (subscribed) {
|
||||||
setPosts(posts);
|
setPosts(posts);
|
||||||
@@ -83,6 +87,7 @@ let Feed = ({ navigation, route }) => {
|
|||||||
maxToRenderPerBatch={3}
|
maxToRenderPerBatch={3}
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
style={styles.container}
|
style={styles.container}
|
||||||
|
ref={flatListRef}
|
||||||
/>
|
/>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { useEffect, useRef } from "react";
|
||||||
import { Searchbar, Title } from 'react-native-paper';
|
import { Searchbar, Title, IconButton } from 'react-native-paper';
|
||||||
import { StyleSheet, SafeAreaView, FlatList } from 'react-native';
|
import { StyleSheet, SafeAreaView, FlatList, View } from 'react-native';
|
||||||
import API from "../API";
|
import API from "../API";
|
||||||
import GroupCard from "../components/GroupCard";
|
import GroupCard from "../components/GroupCard";
|
||||||
|
|
||||||
const Groups = () => {
|
const Groups = ({navigation}) => {
|
||||||
const [searchQuery, setSearchQuery] = React.useState('');
|
const [searchQuery, setSearchQuery] = React.useState('');
|
||||||
|
const [searchVisible, setSearchVisible] = React.useState(false);
|
||||||
const [groups, setGroups] = React.useState([]);
|
const [groups, setGroups] = React.useState([]);
|
||||||
const [queryTimer, setQueryTimer] = React.useState(0);
|
const [queryTimer, setQueryTimer] = React.useState(0);
|
||||||
|
const searchTextBox = useRef(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let subscribed = true;
|
let subscribed = true;
|
||||||
@@ -43,18 +45,53 @@ const Groups = () => {
|
|||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={{ flex: 1 }}>
|
<SafeAreaView style={{ flex: 1 }}>
|
||||||
<Searchbar
|
|
||||||
placeholder="Search Groups"
|
|
||||||
onChangeText={onChangeSearch}
|
|
||||||
value={searchQuery}
|
|
||||||
/>
|
|
||||||
<FlatList
|
<FlatList
|
||||||
contentContainerStyle={styles.container}
|
contentContainerStyle={styles.container}
|
||||||
numColumns={1}
|
numColumns={1}
|
||||||
data={groups}
|
data={groups}
|
||||||
renderItem={renderProfile}
|
renderItem={renderProfile}
|
||||||
keyExtractor={item => item._id}
|
keyExtractor={item => item._id}
|
||||||
ListHeaderComponent={searchQuery ? <></> : <Title style={styles.title} >Groups you follow:</Title>}
|
ListHeaderComponent={
|
||||||
|
<>
|
||||||
|
<View style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: "100%",
|
||||||
|
zIndex: 100
|
||||||
|
}}>
|
||||||
|
{!searchVisible ?
|
||||||
|
<View style={{
|
||||||
|
alignSelf:"flex-end",
|
||||||
|
flex:1,
|
||||||
|
flexDirection: "row"
|
||||||
|
}}>
|
||||||
|
<IconButton icon={'add'} size={35} onPress={()=>{
|
||||||
|
navigation.navigate('NewGroup');
|
||||||
|
}} />
|
||||||
|
<IconButton icon={'search'} size={35} onPress={()=>{
|
||||||
|
setSearchVisible(true);
|
||||||
|
console.log(searchTextBox)
|
||||||
|
//searchTextBox.current.focus();
|
||||||
|
}} />
|
||||||
|
</View> :
|
||||||
|
<Searchbar
|
||||||
|
placeholder="Search Groups"
|
||||||
|
onChangeText={onChangeSearch}
|
||||||
|
value={searchQuery}
|
||||||
|
clearButtonMode="while-editing"
|
||||||
|
blurOnSubmit={true}
|
||||||
|
onBlur={()=>{
|
||||||
|
setSearchVisible(false);
|
||||||
|
}}
|
||||||
|
forwardRef={searchTextBox}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</View>
|
||||||
|
<Title style={styles.title} >{searchQuery ? "Results:" : "Your Groups:"}</Title>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
style={{backgroundColor: "#edf2f7",}}
|
||||||
/>
|
/>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
)
|
)
|
||||||
@@ -68,6 +105,7 @@ const styles = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
padding: 10,
|
padding: 10,
|
||||||
|
paddingTop:5,
|
||||||
fontSize: 30,
|
fontSize: 30,
|
||||||
marginTop: 15,
|
marginTop: 15,
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
|
|||||||
39
Views/NewGroup.js
Normal file
39
Views/NewGroup.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { Searchbar, Title, IconButton } from 'react-native-paper';
|
||||||
|
import { StyleSheet, SafeAreaView, ImageBackground, View } from 'react-native';
|
||||||
|
import API from "../API";
|
||||||
|
import GroupCard from "../components/GroupCard";
|
||||||
|
|
||||||
|
const NewGroup = () => {
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SafeAreaView style={{ padding: 10, backgroundColor: "#edf2f7", flex:1 }}>
|
||||||
|
<ImageBackground source={require("../assets/settings.png")}
|
||||||
|
style={{flex:1}}
|
||||||
|
imageStyle={{resizeMode:"contain", opacity: 0.05}}
|
||||||
|
>
|
||||||
|
<Title style={styles.title}>New Group:</Title>
|
||||||
|
</ImageBackground>
|
||||||
|
</SafeAreaView>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NewGroup;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
padding: 5,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
padding: 10,
|
||||||
|
paddingTop:5,
|
||||||
|
fontSize: 30,
|
||||||
|
marginTop: 15,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#777"
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -60,11 +60,11 @@ let ProfileCard = ({ profileid, hideIcon, profileObj }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card style={styles.content}>
|
<Card style={styles.content}>
|
||||||
<Card.Content>
|
<Card.Content style={{padding:0}}>
|
||||||
<IconButton icon={icon} style={{
|
<IconButton icon={icon} style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
right: 5,
|
right: 0,
|
||||||
top: 5,
|
top: 0,
|
||||||
}} />
|
}} />
|
||||||
<List.Item
|
<List.Item
|
||||||
title={profile.profile?.firstName + " " + profile.profile?.lastName}
|
title={profile.profile?.firstName + " " + profile.profile?.lastName}
|
||||||
@@ -74,6 +74,7 @@ let ProfileCard = ({ profileid, hideIcon, profileObj }) => {
|
|||||||
descriptionStyle={{}}
|
descriptionStyle={{}}
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
descriptionNumberOfLines={4}
|
descriptionNumberOfLines={4}
|
||||||
|
style={{padding:0}}
|
||||||
/>
|
/>
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -86,6 +87,8 @@ export default React.memo(ProfileCard);
|
|||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
content: {
|
content: {
|
||||||
margin: 4,
|
margin: 4,
|
||||||
|
padding: 0,
|
||||||
|
borderRadius: 10,
|
||||||
},
|
},
|
||||||
centerItems: {
|
centerItems: {
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
|||||||
@@ -124,7 +124,8 @@ const styles = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
card: {
|
card: {
|
||||||
margin: 8,
|
margin: 8,
|
||||||
backgroundColor: "#FFFFFF"
|
backgroundColor: "#FFFFFF",
|
||||||
|
borderRadius: 10,
|
||||||
},
|
},
|
||||||
comment: {
|
comment: {
|
||||||
margin: 8,
|
margin: 8,
|
||||||
|
|||||||
Reference in New Issue
Block a user