aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Kim <brian@tagg.id>2021-05-14 19:33:03 -0700
committerBrian Kim <brian@tagg.id>2021-05-14 19:33:03 -0700
commit37b37f296a59aea43e73f615ae6cb042b2242e87 (patch)
tree843caf5c4c79ce41fa2a2837bf6075e4abed9533
parente884ad25b4f2358406eee8a2766890291538a518 (diff)
Bug fixes
-rw-r--r--src/components/common/Avatar.tsx23
-rw-r--r--src/components/profile/Cover.tsx64
-rw-r--r--src/components/profile/ProfileHeader.tsx1
-rw-r--r--src/components/profile/TaggAvatar.tsx66
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;