diff options
| author | Ivan Chen <ivan@tagg.id> | 2021-05-13 15:23:16 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-13 15:23:16 -0400 |
| commit | 4c1ac793d3b1bc6d0929576ce7ea6354f3ef1404 (patch) | |
| tree | fe2ef4a130061edd788921b8994eedec01f3b316 /src/components | |
| parent | 0fb9405c949b2dc92e0e834f684a1f938892f230 (diff) | |
| parent | e884ad25b4f2358406eee8a2766890291538a518 (diff) | |
Merge pull request #416 from brian-tagg/plusSignForNewUsers
[TMA-844] Plus sign for profile and header in profile, ability to add on the sc…
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/profile/Cover.tsx | 108 | ||||
| -rw-r--r-- | src/components/profile/TaggAvatar.tsx | 67 |
2 files changed, 157 insertions, 18 deletions
diff --git a/src/components/profile/Cover.tsx b/src/components/profile/Cover.tsx index 27777b64..5d5b4234 100644 --- a/src/components/profile/Cover.tsx +++ b/src/components/profile/Cover.tsx @@ -1,28 +1,93 @@ -import React from 'react'; -import {Image, StyleSheet, View} from 'react-native'; -import {useSelector} from 'react-redux'; +import React, {useState, useEffect} from 'react'; +import { + Image, + StyleSheet, + View, + TouchableOpacity, + Text, + ImageBackground, +} from 'react-native'; import {COVER_HEIGHT, IMAGE_WIDTH} from '../../constants'; -import {RootState} from '../../store/rootreducer'; import {ScreenType} from '../../types'; +import GreyPurplePlus from '../../assets/icons/grey-purple-plus.svg'; +import {useDispatch, useSelector} from 'react-redux'; +import {loadUserData, resetHeaderAndProfileImage} from '../../store/actions'; +import {RootState} from '../../store/rootreducer'; +import {normalize, patchProfile, validateImageLink} from '../../utils'; interface CoverProps { userXId: string | undefined; screenType: ScreenType; } const Cover: React.FC<CoverProps> = ({userXId, screenType}) => { - const {cover} = useSelector((state: RootState) => + const dispatch = useDispatch(); + const {cover, user} = useSelector((state: RootState) => userXId ? state.userX[screenType][userXId] : state.user, ); - return ( - <View style={[styles.container]}> - <Image - style={styles.image} - defaultSource={require('../../assets/images/cover-placeholder.png')} - source={{uri: cover, cache: 'reload'}} - /> - </View> - ); + const [needsUpdate, setNeedsUpdate] = useState(false); + const [loading, setLoading] = useState(false); + const [validImage, setValidImage] = useState<boolean>(true); + + useEffect(() => { + checkAvatar(cover); + }, []); + + useEffect(() => { + if (needsUpdate) { + const userId = user.userId; + const username = user.username; + dispatch(resetHeaderAndProfileImage()); + dispatch(loadUserData({userId, username})); + } + }, [dispatch, needsUpdate]); + + const handleNewImage = async () => { + setLoading(true); + const result = await patchProfile('header', user.userId); + setLoading(true); + if (result) { + setNeedsUpdate(true); + } else { + setLoading(false); + } + }; + + const checkAvatar = async (url: string | undefined) => { + const valid = await validateImageLink(url); + if (valid !== validImage) { + setValidImage(valid); + } + }; + + 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'}}> + <TouchableOpacity + accessible={true} + accessibilityLabel="ADD HEADER PICTURE" + onPress={() => handleNewImage()}> + <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> + ); + } }; const styles = StyleSheet.create({ @@ -33,5 +98,20 @@ const styles = StyleSheet.create({ width: IMAGE_WIDTH, height: COVER_HEIGHT, }, + plus: { + position: 'absolute', + top: 75, + right: 125, + }, + text: { + color: 'white', + position: 'absolute', + fontSize: normalize(16), + top: 80, + right: 20, + }, + touch: { + flex: 1, + }, }); export default Cover; diff --git a/src/components/profile/TaggAvatar.tsx b/src/components/profile/TaggAvatar.tsx index ea0bdb65..304b9e3a 100644 --- a/src/components/profile/TaggAvatar.tsx +++ b/src/components/profile/TaggAvatar.tsx @@ -1,9 +1,12 @@ -import React from 'react'; -import {StyleSheet} from 'react-native'; -import {useSelector} from 'react-redux'; +import React, {useState, useEffect} from 'react'; +import {StyleSheet, TouchableOpacity} from 'react-native'; import {RootState} from '../../store/rootreducer'; import {ScreenType} from '../../types'; import {Avatar} from '../common'; +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'; const PROFILE_DIM = 100; @@ -20,8 +23,59 @@ const TaggAvatar: React.FC<TaggAvatarProps> = ({ const {avatar} = useSelector((state: RootState) => userXId ? state.userX[screenType][userXId] : state.user, ); + const dispatch = useDispatch(); + const [needsUpdate, setNeedsUpdate] = useState(false); + const [loading, setLoading] = useState(false); + const [validImage, setValidImage] = useState<boolean>(true); + const {user} = useSelector((state: RootState) => + userXId ? state.userX[screenType][userXId] : state.user, + ); + + useEffect(() => { + checkAvatar(avatar); + }, []); + + useEffect(() => { + if (needsUpdate) { + const userId = user.userId; + const username = user.username; + dispatch(resetHeaderAndProfileImage()); + dispatch(loadUserData({userId, username})); + } + }, [dispatch, needsUpdate]); - return <Avatar style={[styles.image, style]} uri={avatar} />; + const handleNewImage = async () => { + setLoading(true); + const result = await patchProfile('profile', user.userId); + if (result) { + setNeedsUpdate(true); + } else { + setLoading(false); + } + }; + + const checkAvatar = async (url: string | undefined) => { + const valid = await validateImageLink(url); + if (valid !== validImage) { + setValidImage(valid); + } + }; + + 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} />; + } }; const styles = StyleSheet.create({ @@ -30,6 +84,11 @@ const styles = StyleSheet.create({ width: PROFILE_DIM, borderRadius: PROFILE_DIM / 2, }, + plus: { + position: 'absolute', + bottom: 35, + right: 0, + }, }); export default TaggAvatar; |
