diff options
author | Ivan Chen <ivan@thetaggid.com> | 2020-12-29 20:21:24 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-29 20:21:24 -0500 |
commit | bd2f89805d0bb1c2f1d08fe8d91099aa4f109d35 (patch) | |
tree | ac7219e034a0c4035096c6df8dbe6b92446b5111 /src/components | |
parent | ec478d4981c726856485b49b49ac33b0d9e6a903 (diff) |
[TMA-461] Notifications Screen (#151)
* renamed ProfileStack to MainStack, created initial notifications data type
* cleaned up code
* added notifications to redux
* finished sectioned list
* updated types to make more sense
* finished sectioned notifications by date
* updated notification type and tested mock backend integration
* finished read or unread logic
* minor changes
* another minor fix
* finished integration
* moved stuff
* added ability to navigate to user profile
Co-authored-by: Husam Salhab <47015061+hsalhab@users.noreply.github.com>
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/notifications/Notification.tsx | 150 | ||||
-rw-r--r-- | src/components/notifications/index.ts | 1 | ||||
-rw-r--r-- | src/components/profile/ProfilePreview.tsx | 35 |
3 files changed, 159 insertions, 27 deletions
diff --git a/src/components/notifications/Notification.tsx b/src/components/notifications/Notification.tsx new file mode 100644 index 00000000..f533e42d --- /dev/null +++ b/src/components/notifications/Notification.tsx @@ -0,0 +1,150 @@ +import {useNavigation} from '@react-navigation/native'; +import React, {useEffect, useState} from 'react'; +import {Image, StyleSheet, Text, View} from 'react-native'; +import {TouchableWithoutFeedback} from 'react-native-gesture-handler'; +import {useDispatch, useStore} from 'react-redux'; +import {loadAvatar} from '../../services'; +import {RootState} from '../../store/rootReducer'; +import {NotificationType, ScreenType} from '../../types'; +import {fetchUserX, SCREEN_HEIGHT, userXInStore} from '../../utils'; + +interface NotificationProps { + item: NotificationType; + screenType: ScreenType; +} + +const Notification: React.FC<NotificationProps> = (props) => { + const { + item: { + actor: {id, username, first_name, last_name}, + verbage, + notification_type, + notification_object, + unread, + }, + screenType, + } = props; + const navigation = useNavigation(); + const state: RootState = useStore().getState(); + const dispatch = useDispatch(); + + const [avatarURI, setAvatarURI] = useState<string | undefined>(undefined); + const [momentURI, setMomentURI] = useState<string | undefined>(undefined); + const backgroundColor = unread ? '#DCF1F1' : 'rgba(0,0,0,0)'; + + useEffect(() => { + let mounted = true; + const loadAvatarImage = async (user_id: string) => { + const response = await loadAvatar(user_id, true); + if (mounted) { + setAvatarURI(response); + } + }; + loadAvatarImage(id); + return () => { + mounted = false; + }; + }, [id]); + + // TODO: this should be moment thumbnail, waiting for that to complete + // useEffect(() => { + // let mounted = true; + // const loadMomentImage = async (user_id: string) => { + // const response = await loadAvatar(user_id, true); + // if (mounted) { + // setMomentURI(response); + // } + // }; + // loadMomentImage(id); + // return () => { + // mounted = false; + // }; + // }, [id, notification_object]); + + const onNotificationTap = async () => { + switch (notification_type) { + case 'FLO': + if (!userXInStore(state, screenType, id)) { + await fetchUserX( + dispatch, + {userId: id, username: username}, + screenType, + ); + } + navigation.push('Profile', { + userXId: id, + screenType, + }); + break; + default: + break; + } + }; + + return ( + <TouchableWithoutFeedback + style={[styles.container, {backgroundColor}]} + onPress={onNotificationTap}> + <View style={styles.avatarContainer}> + <Image + style={styles.avatar} + source={ + avatarURI + ? {uri: avatarURI, cache: 'only-if-cached'} + : require('../../assets/images/avatar-placeholder.png') + } + /> + </View> + <View style={styles.contentContainer}> + <Text style={styles.actorName}> + {first_name} {last_name} + </Text> + <Text>{verbage}</Text> + </View> + {/* TODO: Still WIP */} + {/* {notification_type === 'CMT' && notification_object && ( + <Image + style={styles.moment} + source={{uri: momentURI, cache: 'only-if-cached'}} + /> + )} */} + </TouchableWithoutFeedback> + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: 'row', + height: SCREEN_HEIGHT / 12, + flex: 1, + alignItems: 'center', + }, + avatarContainer: { + marginLeft: '5%', + flex: 1, + justifyContent: 'center', + }, + avatar: { + height: 42, + width: 42, + borderRadius: 20, + }, + contentContainer: { + flex: 5, + marginLeft: '5%', + height: '80%', + flexDirection: 'column', + justifyContent: 'space-around', + }, + actorName: { + fontWeight: 'bold', + }, + moment: { + position: 'absolute', + height: 42, + width: 42, + right: '5%', + }, +}); + +export default Notification; diff --git a/src/components/notifications/index.ts b/src/components/notifications/index.ts new file mode 100644 index 00000000..0260ce24 --- /dev/null +++ b/src/components/notifications/index.ts @@ -0,0 +1 @@ +export {default as Notification} from './Notification'; diff --git a/src/components/profile/ProfilePreview.tsx b/src/components/profile/ProfilePreview.tsx index cc18e457..49c79e2d 100644 --- a/src/components/profile/ProfilePreview.tsx +++ b/src/components/profile/ProfilePreview.tsx @@ -14,12 +14,14 @@ import RNFetchBlob from 'rn-fetch-blob'; import AsyncStorage from '@react-native-community/async-storage'; import {PROFILE_PHOTO_THUMBNAIL_ENDPOINT} from '../../constants'; import {UserType, PreviewType} from '../../types'; -import {isUserBlocked} from '../../services'; +import {isUserBlocked, loadAvatar} from '../../services'; import {useSelector, useDispatch, useStore} from 'react-redux'; import {RootState} from '../../store/rootreducer'; import {logout} from '../../store/actions'; import {fetchUserX, userXInStore} from '../../utils'; +import {SearchResultsBackground} from '../search'; import NavigationBar from 'src/routes/tabs'; + const NO_USER: UserType = { userId: '', username: '', @@ -52,34 +54,13 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({ const dispatch = useDispatch(); useEffect(() => { let mounted = true; - const loadAvatar = async () => { - try { - const token = await AsyncStorage.getItem('token'); - if (!token) { - setUser(NO_USER); - return; - } - const response = await RNFetchBlob.config({ - fileCache: true, - appendExt: 'jpg', - }).fetch('GET', PROFILE_PHOTO_THUMBNAIL_ENDPOINT + `${id}/`, { - Authorization: 'Token ' + token, - }); - const status = response.info().status; - if (status === 200) { - if (mounted) { - setAvatarURI(response.path()); - } - return; - } - if (mounted) { - setAvatarURI(''); - } - } catch (error) { - console.log(error); + const loadAvatarImage = async () => { + const response = await loadAvatar(id, true); + if (mounted) { + setAvatarURI(response); } }; - loadAvatar(); + loadAvatarImage(); return () => { mounted = false; }; |