From dc3079328e14656deeba873b0a5fd2f23b6dc602 Mon Sep 17 00:00:00 2001 From: aeroreyna Date: Wed, 16 Mar 2022 21:47:56 -0700 Subject: [PATCH] Profile Cache and Profile Header Started --- Views/Profile.js | 38 ++++++++++++++++++++++++++++++++++-- components/Media.js | 11 ++++++----- components/Post.js | 39 ++++++++++++++++++++----------------- components/ProfileHeader.js | 35 +++++++++++++++++++++++++++++++++ components/UserName.js | 26 ++++++++++++++++--------- package-lock.json | 27 +++++++++++++++++++++++++ package.json | 13 +++++++------ 7 files changed, 149 insertions(+), 40 deletions(-) create mode 100644 components/ProfileHeader.js diff --git a/Views/Profile.js b/Views/Profile.js index cf4305f..9f5310e 100644 --- a/Views/Profile.js +++ b/Views/Profile.js @@ -4,22 +4,50 @@ 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 ProfileHeader from '../components/ProfileHeader.js'; +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) { + return []; + } +} 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) { - API.getUserProfile(route.params.profileid).then(({ profile }) => { + console.log('Loading Cache Profile:' + route.params.profileid); + getProfilePosts(route.params.profileid).then(setPosts); + console.log('Loaded Cache Profile:' + route.params.profileid); + API.getUserProfile(route.params.profileid).then((profileObj) => { + let profile = profileObj.profile + setProfile(profileObj); navigation.setOptions({ title: profile.firstName + " " + profile.lastName }); }); API.getPosts(route.params.profileid).then((data) => { setPosts(data); + storeProfilePosts(route.params.profileid, data); + console.log('Store Cache Profile:' + route.params.profileid); }); } else { navigation.navigate('Feed') @@ -30,6 +58,12 @@ let Profile = ({ navigation, route }) => { return (<>); return (); }); + const header = ( + + + setPosts([newPost, ...Posts])} /> + + ) return ( @@ -40,7 +74,7 @@ let Profile = ({ navigation, route }) => { data={Posts} renderItem={renderPost} keyExtractor={item => item._id || item.createdAt} - ListHeaderComponent={ setPosts([newPost, ...Posts])} />} + ListHeaderComponent={header} refreshing={Posts.length === 0} onRefresh={() => { API.getPosts(route.params.profileid).then(setPosts); diff --git a/components/Media.js b/components/Media.js index a51ba1f..5f656a6 100644 --- a/components/Media.js +++ b/components/Media.js @@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react'; import { Text, View, ScrollView, Image, StyleSheet } from 'react-native'; import API from './../API.js'; import VideoPlayer from './VideoPlayer.js'; +import VimeoPlayer from './VimeoPlayer.js'; const videoIdF = (content) => { let vimeoTag = content.match(/@vimeo:[0-9]+/); @@ -39,13 +40,13 @@ let Media = (props) => { const imageStyle = imagesTag.length == 1 ? styles.image : styles.multipleImage; const videosId = videoIdF(props.content); let [videosFiles, setVideosFiles] = useState([]); - useEffect(async ()=>{ - if(!videosId[1]) return 0; + useEffect(async () => { + if (!videosId[1]) return 0; let videoObj = await API.getVideo(videosId[1]); - setVideosFiles(videoObj.files); + setVideosFiles(videoObj.files || []); }, [props.content]) - //const vimeo = videosId.length ? : undefined; - const vimeo = videosFiles.length ? : null; + const vimeo = videosFiles.length ? : + (videosId.length ? : <>); return ( diff --git a/components/Post.js b/components/Post.js index a008885..77abf53 100644 --- a/components/Post.js +++ b/components/Post.js @@ -1,5 +1,6 @@ import React, { useState, useEffect } from 'react'; -import { Text, ScrollView, FlatList, StyleSheet, View } from 'react-native'; +import { Text, ScrollView, FlatList, StyleSheet, View, Linking } from 'react-native'; +import Hyperlink from 'react-native-hyperlink' import { Avatar, Button, Card, Title, Chip } from 'react-native-paper'; import API from './../API.js'; import UserName from './UserName.js'; @@ -8,7 +9,6 @@ import Comment from "./Comment"; import NewComment from './NewComment.js'; import Moment from 'moment'; - let Post = (props) => { const viewer = props.viewer; let [showCommentsB, changeshowCommentsB] = useState(false); @@ -18,6 +18,7 @@ let Post = (props) => { let toProfileText = post.toProfile && post.toProfile !== post.profileid ? {">"} : undefined; let cleanContent = post.content.replace(/@[A-z]+:.+\w/g, ''); + //cleanContent = convertLinks(cleanContent); const newComentAdded = (commentData) => { let newPostObj = { ...post }; newPostObj.comments.push(commentData); @@ -54,23 +55,25 @@ let Post = (props) => { return ( - {!post.nonOrganicType ? - - - - {toProfileText} - - {" " + Moment(post.createdAt).fromNow()} + + {!post.nonOrganicType ? + + + + {toProfileText} + + {" " + Moment(post.createdAt).fromNow()} + - - {cleanContent} - - : - - News - {cleanContent} - - } + {cleanContent} + + : + + News + {cleanContent} + + } + + + + {/* + } + subtitle={profileObj.profile.description} + left={(props) => } + right={(props) => { }} />} + /> + */} + + ); + +} + +export default React.memo(ProfileHeader); \ No newline at end of file diff --git a/components/UserName.js b/components/UserName.js index 30a1f70..60e6ccf 100644 --- a/components/UserName.js +++ b/components/UserName.js @@ -1,21 +1,21 @@ import React, { useState, useEffect } from 'react'; -import { Text, View, ScrollView, Button, StyleSheet } from 'react-native'; +import { Text, StyleSheet } from 'react-native'; +import Icon from 'react-native-vector-icons/MaterialIcons'; import API from './../API.js'; import { useNavigation } from '@react-navigation/native'; - import AsyncStorage from '@react-native-async-storage/async-storage'; const storeName = async (key, value) => { try { const jsonValue = JSON.stringify(value) - await AsyncStorage.setItem('Name_'+key, jsonValue) + await AsyncStorage.setItem('Name_' + key, jsonValue) } catch (e) { } } const getName = async (key) => { try { - const value = await AsyncStorage.getItem('Name_'+key) + const value = await AsyncStorage.getItem('Name_' + key) if (value !== null) { return JSON.parse(value); } @@ -24,25 +24,33 @@ const getName = async (key) => { } } -let UserName = ({profileid}) => { +let UserName = ({ profileid }) => { let [profile, setProfile] = useState({}); const navigation = useNavigation(); useEffect(async () => { let cacheProfile = await getName(profileid); - if(cacheProfile && cacheProfile.profile) setProfile(cacheProfile); + if (cacheProfile && cacheProfile.profile) setProfile(cacheProfile); let p = await API.getUserProfile(profileid).catch(() => { return {} }); setProfile(p); storeName(profileid, p) }, [profileid]); - const onPress = ()=>{ - return navigation.navigate('Profile', { profileid }) + let icon = profile._id ? (!profile.isGroup ? "person-outline" : "group") : ''; + icon = icon === "person-outline" && profile.subscription && profile.subscription > (new Date() - 0) ? "assignment-ind" : icon; + icon = icon === "group" && profile.isCourse ? "subscriptions" : icon; + + const onPress = () => { + return navigation.navigate('Profile', { profileid }) } return ( - {profile.profile && profile.profile.firstName} {profile.profile && profile.profile.lastName} + + + + {profile.profile && profile.profile.firstName} {profile.profile && profile.profile.lastName} + ); } diff --git a/package-lock.json b/package-lock.json index fb0bf6f..648ae2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5452,6 +5452,14 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "requires": { + "uc.micro": "^1.0.1" + } + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -5601,6 +5609,11 @@ "buffer-alloc": "^1.1.0" } }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, "merge-options": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", @@ -7008,6 +7021,15 @@ "nullthrows": "^1.1.1" } }, + "react-native-hyperlink": { + "version": "0.0.19", + "resolved": "https://registry.npmjs.org/react-native-hyperlink/-/react-native-hyperlink-0.0.19.tgz", + "integrity": "sha512-x4wuRGDMnnpWcRr5MCK1D2UcEuzD9IHK8lfjEhO/+QqXNaX31HdeD3ss3BXXZgHxpRYtLbTB0TuFcl1HHANp3w==", + "requires": { + "linkify-it": "^2.2.0", + "mdurl": "^1.0.0" + } + }, "react-native-iphone-x-helper": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz", @@ -8305,6 +8327,11 @@ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==" }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, "uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", diff --git a/package.json b/package.json index f4a8e3c..1f3a5f7 100644 --- a/package.json +++ b/package.json @@ -10,28 +10,29 @@ "eject": "expo eject" }, "dependencies": { + "@react-native-async-storage/async-storage": "~1.15.0", "@react-navigation/material-bottom-tabs": "^6.1.1", "@react-navigation/native": "^6.0.8", "@react-navigation/native-stack": "^6.5.0", "expo": "~43.0.2", + "expo-av": "~10.1.3", + "expo-device": "~4.0.3", + "expo-notifications": "~0.13.3", "expo-status-bar": "~1.1.0", + "expo-updates": "~0.10.15", "moment": "^2.29.1", "react": "17.0.1", "react-dom": "17.0.1", "react-google-material-icons": "^1.0.4", "react-native": "0.64.3", "react-native-autoheight-webview": "^1.6.1", + "react-native-hyperlink": "0.0.19", "react-native-paper": "^4.11.2", "react-native-safe-area-context": "^4.1.2", "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-async-storage/async-storage": "~1.15.0", - "expo-av": "~10.1.3", - "expo-notifications": "~0.13.3", - "expo-device": "~4.0.3", - "expo-updates": "~0.10.15" + "react-native-webview": "^11.17.2" }, "devDependencies": { "@babel/core": "^7.12.9"