diff options
author | Brian Kim <brian@tagg.id> | 2021-05-14 19:33:03 -0700 |
---|---|---|
committer | Brian Kim <brian@tagg.id> | 2021-05-14 19:33:03 -0700 |
commit | 37b37f296a59aea43e73f615ae6cb042b2242e87 (patch) | |
tree | 843caf5c4c79ce41fa2a2837bf6075e4abed9533 /src | |
parent | e884ad25b4f2358406eee8a2766890291538a518 (diff) |
Bug fixes
Diffstat (limited to 'src')
-rw-r--r-- | src/components/common/Avatar.tsx | 23 | ||||
-rw-r--r-- | src/components/profile/Cover.tsx | 64 | ||||
-rw-r--r-- | src/components/profile/ProfileHeader.tsx | 1 | ||||
-rw-r--r-- | src/components/profile/TaggAvatar.tsx | 66 |
4 files changed, 105 insertions, 49 deletions
diff --git a/src/components/common/Avatar.tsx b/src/components/common/Avatar.tsx index 831cf906..86ebedf3 100644 --- a/src/components/common/Avatar.tsx +++ b/src/components/common/Avatar.tsx @@ -1,17 +1,30 @@ import React, {FC} from 'react'; -import {Image, ImageStyle, StyleProp} from 'react-native'; +import {Image, ImageStyle, StyleProp, ImageBackground} from 'react-native'; type AvatarProps = { style: StyleProp<ImageStyle>; uri: string | undefined; + loading: boolean; + loadingStyle: StyleProp<ImageStyle> | undefined; }; -const Avatar: FC<AvatarProps> = ({style, uri}) => { +const Avatar: FC<AvatarProps> = ({ + style, + uri, + loading = false, + loadingStyle, +}) => { return ( - <Image + <ImageBackground style={style} defaultSource={require('../../assets/images/avatar-placeholder.png')} - source={{uri, cache: 'reload'}} - /> + source={{uri, cache: 'reload'}}> + {loading && ( + <Image + source={require('../../assets/gifs/loading-animation.gif')} + style={loadingStyle} + /> + )} + </ImageBackground> ); }; diff --git a/src/components/profile/Cover.tsx b/src/components/profile/Cover.tsx index 5d5b4234..2b6268a6 100644 --- a/src/components/profile/Cover.tsx +++ b/src/components/profile/Cover.tsx @@ -14,6 +14,7 @@ import {useDispatch, useSelector} from 'react-redux'; import {loadUserData, resetHeaderAndProfileImage} from '../../store/actions'; import {RootState} from '../../store/rootreducer'; import {normalize, patchProfile, validateImageLink} from '../../utils'; +import {useIsFocused} from '@react-navigation/native'; interface CoverProps { userXId: string | undefined; @@ -26,14 +27,22 @@ const Cover: React.FC<CoverProps> = ({userXId, screenType}) => { ); const [needsUpdate, setNeedsUpdate] = useState(false); - const [loading, setLoading] = useState(false); + const [updating, setUpdating] = useState(false); + const [loading, setLoading] = useState(true); const [validImage, setValidImage] = useState<boolean>(true); + const isFocused = useIsFocused(); useEffect(() => { - checkAvatar(cover); + checkCover(cover); + setLoading(false); }, []); useEffect(() => { + checkCover(cover); + }, [cover, isFocused]); + + useEffect(() => { + checkCover(cover); if (needsUpdate) { const userId = user.userId; const username = user.username; @@ -47,26 +56,35 @@ const Cover: React.FC<CoverProps> = ({userXId, screenType}) => { const result = await patchProfile('header', user.userId); setLoading(true); if (result) { + setUpdating(true); setNeedsUpdate(true); + setLoading(false); } else { setLoading(false); } }; - const checkAvatar = async (url: string | undefined) => { + const checkCover = async (url: string | undefined) => { const valid = await validateImageLink(url); if (valid !== validImage) { setValidImage(valid); } + setLoading(false); }; - if (!validImage && userXId === undefined && !loading) { - return ( - <View style={[styles.container]}> - <ImageBackground - style={styles.image} - defaultSource={require('../../assets/images/cover-placeholder.png')} - source={{uri: cover, cache: 'reload'}}> + return ( + <View style={styles.container}> + <ImageBackground + style={styles.image} + defaultSource={require('../../assets/images/cover-placeholder.png')} + source={{uri: cover, cache: 'reload'}}> + {loading && ( + <Image + source={require('../../assets/gifs/loading-animation.gif')} + style={styles.loadingLarge} + /> + )} + {!validImage && userXId === undefined && !loading && !updating && ( <TouchableOpacity accessible={true} accessibilityLabel="ADD HEADER PICTURE" @@ -74,20 +92,10 @@ const Cover: React.FC<CoverProps> = ({userXId, screenType}) => { <GreyPurplePlus style={styles.plus} /> <Text style={styles.text}>Add Picture</Text> </TouchableOpacity> - </ImageBackground> - </View> - ); - } else { - return ( - <View style={styles.container}> - <Image - style={styles.image} - defaultSource={require('../../assets/images/cover-placeholder.png')} - source={{uri: cover, cache: 'reload'}} - /> - </View> - ); - } + )} + </ImageBackground> + </View> + ); }; const styles = StyleSheet.create({ @@ -113,5 +121,13 @@ const styles = StyleSheet.create({ touch: { flex: 1, }, + loadingLarge: { + alignSelf: 'center', + justifyContent: 'center', + height: COVER_HEIGHT * 0.2, + width: IMAGE_WIDTH * 0.2, + aspectRatio: 1, + top: 100, + }, }); export default Cover; diff --git a/src/components/profile/ProfileHeader.tsx b/src/components/profile/ProfileHeader.tsx index 14f7dc71..f3bc8e4b 100644 --- a/src/components/profile/ProfileHeader.tsx +++ b/src/components/profile/ProfileHeader.tsx @@ -115,6 +115,7 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({ style={styles.avatar} userXId={userXId} screenType={screenType} + editable={true} /> <View style={styles.header}> <Text style={styles.name} numberOfLines={2}> diff --git a/src/components/profile/TaggAvatar.tsx b/src/components/profile/TaggAvatar.tsx index 304b9e3a..8ccae2ef 100644 --- a/src/components/profile/TaggAvatar.tsx +++ b/src/components/profile/TaggAvatar.tsx @@ -7,6 +7,7 @@ import {useDispatch, useSelector} from 'react-redux'; import {loadUserData, resetHeaderAndProfileImage} from '../../store/actions'; import PurplePlus from '../../assets/icons/purple-plus.svg'; import {patchProfile, validateImageLink} from '../../utils'; +import {useIsFocused} from '@react-navigation/native'; const PROFILE_DIM = 100; @@ -14,28 +15,35 @@ interface TaggAvatarProps { style?: object; userXId: string | undefined; screenType: ScreenType; + editable: boolean; } const TaggAvatar: React.FC<TaggAvatarProps> = ({ style, screenType, userXId, + editable = false, }) => { - const {avatar} = useSelector((state: RootState) => + const {avatar, user} = useSelector((state: RootState) => userXId ? state.userX[screenType][userXId] : state.user, ); const dispatch = useDispatch(); const [needsUpdate, setNeedsUpdate] = useState(false); - const [loading, setLoading] = useState(false); + const [updating, setUpdating] = useState(false); + const [loading, setLoading] = useState(true); const [validImage, setValidImage] = useState<boolean>(true); - const {user} = useSelector((state: RootState) => - userXId ? state.userX[screenType][userXId] : state.user, - ); + const isFocused = useIsFocused(); useEffect(() => { checkAvatar(avatar); + setLoading(false); }, []); useEffect(() => { + checkAvatar(avatar); + }, [avatar, isFocused]); + + useEffect(() => { + checkAvatar(avatar); if (needsUpdate) { const userId = user.userId; const username = user.username; @@ -47,8 +55,11 @@ const TaggAvatar: React.FC<TaggAvatarProps> = ({ const handleNewImage = async () => { setLoading(true); const result = await patchProfile('profile', user.userId); + setLoading(true); if (result) { + setUpdating(true); setNeedsUpdate(true); + setLoading(false); } else { setLoading(false); } @@ -61,21 +72,28 @@ const TaggAvatar: React.FC<TaggAvatarProps> = ({ } }; - if (!validImage && userXId === undefined && !loading) { - return ( - <> - <Avatar style={[styles.image, style]} uri={avatar} /> - <TouchableOpacity - accessible={true} - accessibilityLabel="ADD PROFILE PICTURE" - onPress={() => handleNewImage()}> - <PurplePlus style={styles.plus} /> - </TouchableOpacity> - </> - ); - } else { - return <Avatar style={[styles.image, style]} uri={avatar} />; - } + return ( + <> + <Avatar + style={[styles.image, style]} + uri={avatar} + loading={loading} + loadingStyle={styles.loadingLarge} + /> + {editable && + !validImage && + userXId === undefined && + !loading && + !updating && ( + <TouchableOpacity + accessible={true} + accessibilityLabel="ADD PROFILE PICTURE" + onPress={() => handleNewImage()}> + <PurplePlus style={styles.plus} /> + </TouchableOpacity> + )} + </> + ); }; const styles = StyleSheet.create({ @@ -83,12 +101,20 @@ const styles = StyleSheet.create({ height: PROFILE_DIM, width: PROFILE_DIM, borderRadius: PROFILE_DIM / 2, + overflow: 'hidden', }, plus: { position: 'absolute', bottom: 35, right: 0, }, + loadingLarge: { + height: PROFILE_DIM * 0.8, + width: PROFILE_DIM * 0.8, + alignSelf: 'center', + justifyContent: 'center', + aspectRatio: 2, + }, }); export default TaggAvatar; |