292 lines
12 KiB
JavaScript
292 lines
12 KiB
JavaScript
import { StatusBar } from 'expo-status-bar';
|
|
import React, { useState, useEffect } from 'react';
|
|
import { View, ActivityIndicator, StyleSheet, SafeAreaView, FlatList, Alert } from 'react-native';
|
|
import { Button, IconButton } from 'react-native-paper';
|
|
import API from './../API.js';
|
|
import Post from './../components/Post.js';
|
|
import NewPost from "./../components/NewPost.js";
|
|
import ProfileHeader from '../components/ProfileHeader.js';
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
import { useSnapshot } from 'valtio';
|
|
import GlobalState from '../contexts/GlobalState.js';
|
|
|
|
const PROFILE_LOG_PREFIX = '[Profile]';
|
|
const logProfile = (...args) => {
|
|
if (__DEV__) console.log(PROFILE_LOG_PREFIX, ...args);
|
|
};
|
|
|
|
const storeProfilePosts = async (profileid, value) => {
|
|
try {
|
|
const jsonValue = JSON.stringify(value)
|
|
await AsyncStorage.setItem('profile_' + profileid, jsonValue)
|
|
} catch (e) {
|
|
}
|
|
}
|
|
|
|
const getProfilePosts = async (profileid) => {
|
|
try {
|
|
const value = await AsyncStorage.getItem('profile_' + profileid)
|
|
if (value !== null) {
|
|
return JSON.parse(value);
|
|
}
|
|
return [];
|
|
} catch (e) {
|
|
console.log('fail getProfilePosts', e)
|
|
return [];
|
|
}
|
|
}
|
|
|
|
let Profile = ({ navigation, route }) => {
|
|
const viewer = useSnapshot(GlobalState).me || {};
|
|
let [Posts, setPosts] = useState([]);
|
|
let [profile, setProfile] = useState({});
|
|
const [showNewPost, setShowNewPost] = useState(false);
|
|
const [tag, setTag] = useState('');
|
|
const [loading, setLoading] = useState(true);
|
|
const [isDeletingGroup, setIsDeletingGroup] = useState(false);
|
|
|
|
const isOwnedGroup = !!(
|
|
profile?._id &&
|
|
profile?.isGroup &&
|
|
String(profile?.userid || '') === String(viewer?.userid || '')
|
|
);
|
|
|
|
useEffect(() => {
|
|
let subscribed = true;
|
|
const getData = async () => {
|
|
logProfile('load:start', {
|
|
profileid: route?.params?.profileid || null,
|
|
tag,
|
|
});
|
|
setLoading(true);
|
|
setPosts([]);
|
|
if (route.params && route.params.profileid && tag == '') {
|
|
logProfile('cache:read:start', { profileid: route.params.profileid });
|
|
await API.getUserProfile(route.params.profileid).then((profileObj) => {
|
|
if(!subscribed) return 0;
|
|
const nextProfile = profileObj && profileObj._id ? profileObj : {};
|
|
const profileData = nextProfile.profile || {};
|
|
setProfile(nextProfile);
|
|
navigation.setOptions({ title: (profileData.firstName || "") + " " + (profileData.lastName || "") });
|
|
logProfile('profile:loaded', {
|
|
profileid: nextProfile._id || route.params.profileid,
|
|
hasName: !!(profileData.firstName || profileData.lastName),
|
|
});
|
|
});
|
|
await getProfilePosts(route.params.profileid).then((cachedPosts) => {
|
|
const safeCachedPosts = Array.isArray(cachedPosts) ? cachedPosts : [];
|
|
setPosts(safeCachedPosts);
|
|
logProfile('cache:read:end', {
|
|
profileid: route.params.profileid,
|
|
count: safeCachedPosts.length,
|
|
});
|
|
});
|
|
API.getPosts(route.params.profileid).then((data) => {
|
|
if(!subscribed) return 0;
|
|
const safePosts = Array.isArray(data) ? data : [];
|
|
setPosts(safePosts);
|
|
storeProfilePosts(route.params.profileid, safePosts);
|
|
setLoading(false);
|
|
logProfile('network:loaded', {
|
|
profileid: route.params.profileid,
|
|
count: safePosts.length,
|
|
cached: true,
|
|
});
|
|
});
|
|
} else {
|
|
if(route.params && route.params.profileid){
|
|
logProfile('tag:load:start', {
|
|
profileid: route.params.profileid,
|
|
tag,
|
|
});
|
|
API.getPostsWithTag(route.params.profileid, tag).then((data) => {
|
|
if(!subscribed) return 0;
|
|
const safeTagPosts = Array.isArray(data?.posts) ? data.posts : [];
|
|
setPosts(safeTagPosts);
|
|
setLoading(false);
|
|
logProfile('tag:load:end', {
|
|
profileid: route.params.profileid,
|
|
tag,
|
|
count: safeTagPosts.length,
|
|
});
|
|
});
|
|
} else {
|
|
// if no profile information is pressent should load feed
|
|
logProfile('redirect:feed');
|
|
navigation.navigate('Feed')
|
|
}
|
|
}
|
|
logProfile('load:end');
|
|
}
|
|
getData();
|
|
return ()=>{
|
|
subscribed = false;
|
|
logProfile('load:cleanup');
|
|
}
|
|
}, [tag, route.params?.profileid]);
|
|
|
|
const getTagPosts = ()=>{
|
|
API.getPostsWithTag(tag).then((data) => {
|
|
//if(!subscribed) return 0;
|
|
console.log(data.posts);
|
|
setPosts(Array.isArray(data?.posts) ? data.posts : []);
|
|
});
|
|
}
|
|
|
|
const renderPost = (({ item }) => {
|
|
if (item.nonOrganicType)
|
|
return (<></>);
|
|
return (<Post post={item} />);
|
|
});
|
|
|
|
const handleDeleteGroup = () => {
|
|
if (!profile?._id || isDeletingGroup) return;
|
|
Alert.alert(
|
|
"Delete group?",
|
|
"This will permanently delete this group profile.",
|
|
[
|
|
{ text: "Cancel", style: "cancel" },
|
|
{
|
|
text: "Delete",
|
|
style: "destructive",
|
|
onPress: async () => {
|
|
setIsDeletingGroup(true);
|
|
try {
|
|
const result = await API.deleteProfile(profile._id);
|
|
if (result?.status !== "ok") {
|
|
return Alert.alert("Could not delete group", result?.status || "Please try again.");
|
|
}
|
|
const me = await API.getMe();
|
|
if (me && me._id) GlobalState.me = me;
|
|
|
|
if (navigation.canGoBack()) {
|
|
navigation.goBack();
|
|
} else {
|
|
navigation.reset({
|
|
index: 0,
|
|
routes: [{ name: 'MainNavigation' }],
|
|
});
|
|
}
|
|
} catch (error) {
|
|
Alert.alert("Could not delete group", "Please try again.");
|
|
} finally {
|
|
setIsDeletingGroup(false);
|
|
}
|
|
}
|
|
}
|
|
]
|
|
);
|
|
};
|
|
|
|
const header = (
|
|
<View>
|
|
<ProfileHeader profileObj={profile} key={profile._id} />
|
|
<View style={{
|
|
flexDirection: "row",
|
|
alignItems:"center",
|
|
justifyContent: "space-evenly",
|
|
paddingTop: 10
|
|
}}>
|
|
<View style={{
|
|
height: 40,
|
|
width: 40,
|
|
top: 0,
|
|
borderRadius: 28,
|
|
backgroundColor: "#c44d56",
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
elevation: 10,
|
|
zIndex: 1,
|
|
}}>
|
|
<IconButton icon={showNewPost ? 'remove' : "add"} mode="outlined" color="white" onPress={()=>{
|
|
//setShowNewPost(!showNewPost);
|
|
navigation.navigate('NewPost', {toProfile: profile._id})
|
|
}} />
|
|
</View>
|
|
<Button style={{paddingLeft:12, backgroundColor:"#fff"}} title="Images" icon={tag == 'images' ? 'remove' : "image"} mode="outlined" onPress={()=>{
|
|
if(tag == 'images') return setTag('');
|
|
setTag('images');
|
|
}}>{tag == 'images' ? "Images" : ''}</Button>
|
|
<Button style={{paddingLeft:12, backgroundColor:"#fff"}} title="Media" icon={tag == 'media' ? 'remove' : "subscriptions"} mode="outlined" onPress={()=>{
|
|
if(tag == 'media') return setTag('');
|
|
setTag('media');
|
|
}}>{tag == 'media' ? "Media" : ''}</Button>
|
|
<Button style={{paddingLeft:12, backgroundColor:"#fff"}} title="Embedded" icon={tag == 'embedded' ? 'remove' : "folder"} mode="outlined" onPress={()=>{
|
|
if(tag == 'embedded') return setTag('');
|
|
setTag('embedded');
|
|
}}>{tag == 'embedded' ? "Files" : ''}</Button>
|
|
</View>
|
|
{isOwnedGroup ? (
|
|
<View style={styles.deleteGroupRow}>
|
|
<Button
|
|
mode="contained"
|
|
icon="delete"
|
|
buttonColor="#b3261e"
|
|
loading={isDeletingGroup}
|
|
disabled={isDeletingGroup}
|
|
onPress={handleDeleteGroup}
|
|
>
|
|
Delete Group
|
|
</Button>
|
|
</View>
|
|
) : <></>}
|
|
{ showNewPost ?
|
|
<NewPost newPostCB={(newPost) => setPosts([newPost, ...Posts])} />
|
|
: <></>
|
|
}
|
|
</View>
|
|
)
|
|
|
|
return (
|
|
<SafeAreaView style={styles.container}>
|
|
<View>
|
|
{(Posts.length !== 0 || profile._id) ?
|
|
<FlatList
|
|
data={Posts}
|
|
renderItem={renderPost}
|
|
keyExtractor={item => item.lastUpdated || item._id || item.createdAt}
|
|
ListHeaderComponent={header}
|
|
refreshing={loading}
|
|
initialNumToRender={3}
|
|
maxToRenderPerBatch={3}
|
|
removeClippedSubviews={true}
|
|
onRefresh={() => {
|
|
logProfile('refresh:start', {
|
|
profileid: route?.params?.profileid || null,
|
|
tag,
|
|
});
|
|
setLoading(true);
|
|
API.getPosts(route.params.profileid).then((data) => {
|
|
const safePosts = Array.isArray(data) ? data : [];
|
|
setPosts(safePosts);
|
|
storeProfilePosts(route.params.profileid, safePosts);
|
|
setLoading(false);
|
|
logProfile('refresh:end', {
|
|
profileid: route.params.profileid,
|
|
count: safePosts.length,
|
|
cached: true,
|
|
});
|
|
});
|
|
}}
|
|
/> :
|
|
<></> //TODO: Add empty profile card here
|
|
}
|
|
</View>
|
|
<StatusBar style="auto" />
|
|
</SafeAreaView>
|
|
);
|
|
}
|
|
|
|
export default Profile;
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: "#edf2f7",
|
|
},
|
|
deleteGroupRow: {
|
|
paddingHorizontal: 12,
|
|
paddingTop: 12,
|
|
},
|
|
});
|