diff options
author | Ivan Chen <ivan@tagg.id> | 2021-02-01 16:01:03 -0500 |
---|---|---|
committer | Ivan Chen <ivan@tagg.id> | 2021-02-01 16:01:03 -0500 |
commit | 8d1013e86cf2d66671c337d49a80da157802ad86 (patch) | |
tree | 656b1656068bb6636919359d4faaf7051994ff74 /src/components/notifications | |
parent | 951d85348acef13ec7830629205c30ad5f766bee (diff) | |
parent | 7a09cc96bf1fe468a612bb44362bbef24fccc773 (diff) |
Merge branch 'master' into TMA-546-Onboarding-Page
Diffstat (limited to 'src/components/notifications')
-rw-r--r-- | src/components/notifications/Notification.tsx | 114 |
1 files changed, 85 insertions, 29 deletions
diff --git a/src/components/notifications/Notification.tsx b/src/components/notifications/Notification.tsx index e6d16f82..e0ae231e 100644 --- a/src/components/notifications/Notification.tsx +++ b/src/components/notifications/Notification.tsx @@ -1,25 +1,30 @@ import {useNavigation} from '@react-navigation/native'; import React, {useEffect, useState} from 'react'; -import {Image, StyleSheet, Text, View} from 'react-native'; -import {Button} from 'react-native-elements'; +import {Alert, Image, StyleSheet, Text, View} from 'react-native'; import {TouchableWithoutFeedback} from 'react-native-gesture-handler'; import {useDispatch, useStore} from 'react-redux'; +import {ERROR_DELETED_OBJECT} from '../../constants/strings'; import { + loadImageFromURL, + loadMoments, + loadMomentThumbnail, +} from '../../services'; +import { + acceptFriendRequest, declineFriendRequest, loadUserNotifications, + updateReplyPosted, updateUserXFriends, } from '../../store/actions'; -import {acceptFriendRequest} from '../../store/actions'; -import {NotificationType, ProfilePreviewType, ScreenType, MomentType} from '../../types'; +import {RootState} from '../../store/rootReducer'; +import {MomentType, NotificationType, ScreenType} from '../../types'; import { fetchUserX, + getTokenOrLogout, SCREEN_HEIGHT, - SCREEN_WIDTH, userXInStore, } from '../../utils'; import AcceptDeclineButtons from '../common/AcceptDeclineButtons'; -import {loadAvatar, loadMomentThumbnail} from '../../services'; - interface NotificationProps { item: NotificationType; @@ -30,7 +35,7 @@ interface NotificationProps { const Notification: React.FC<NotificationProps> = (props) => { const { item: { - actor: {id, username, first_name, last_name}, + actor: {id, username, first_name, last_name, thumbnail_url}, verbage, notification_type, notification_object, @@ -44,22 +49,29 @@ const Notification: React.FC<NotificationProps> = (props) => { const state: RootState = useStore().getState(); const dispatch = useDispatch(); - const [avatarURI, setAvatarURI] = useState<string | undefined>(undefined); + const [avatar, setAvatar] = useState<string | undefined>(undefined); const [momentURI, setMomentURI] = useState<string | undefined>(undefined); const backgroundColor = unread ? '#DCF1F1' : 'rgba(0,0,0,0)'; + const [onTapLoadProfile, setOnTapLoadProfile] = useState<boolean>(false); + useEffect(() => { - let mounted = true; - const loadAvatarImage = async (user_id: string) => { - const response = await loadAvatar(user_id, true); - if (mounted) { - setAvatarURI(response); + (async () => { + const response = await loadImageFromURL(thumbnail_url); + if (response) { + setAvatar(response); } - }; - loadAvatarImage(id); + })(); + }, []); + + useEffect(() => { + if (onTapLoadProfile) { + fetchUserX(dispatch, {userId: id, username: username}, screenType); + } return () => { - mounted = false; + setOnTapLoadProfile(false); }; - }, [id]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [onTapLoadProfile]); useEffect(() => { let mounted = true; @@ -70,7 +82,11 @@ const Notification: React.FC<NotificationProps> = (props) => { } }; if (notification_type === 'CMT' && notification_object) { - loadMomentImage(notification_object.moment_id); + loadMomentImage( + notification_object.moment_id + ? notification_object.moment_id + : notification_object.parent_comment.moment_id, + ); return () => { mounted = false; }; @@ -94,20 +110,58 @@ const Notification: React.FC<NotificationProps> = (props) => { }); break; case 'CMT': - // find the moment we need to display - const moment = loggedInUserMoments?.find( - (m) => m.moment_id === notification_object?.moment_id, + //Notification object is set to null if the comment / comment_thread / moment gets deleted + if (!notification_object) { + Alert.alert(ERROR_DELETED_OBJECT); + break; + } + let {moment_id} = notification_object; + let {comment_id} = notification_object; + + //If this is a thread, get comment_id and moment_id from parent_comment + if (!notification_object?.moment_id) { + moment_id = notification_object?.parent_comment?.moment_id; + comment_id = notification_object?.parent_comment?.comment_id; + } + + // Now find the moment we need to display + let moment: MomentType | undefined = loggedInUserMoments?.find( + (m) => m.moment_id === moment_id, ); + let userXId; + + // If moment does not belong to the logged in user, then the comment was probably a reply to logged in user's comment + // on userX's moment + // Load moments for userX + if (!moment) { + let moments: MomentType[] = []; + try { + //Populate local state in the mean time + setOnTapLoadProfile(true); + const token = await getTokenOrLogout(dispatch); + moments = await loadMoments(id, token); + } catch (err) { + console.log(err); + } + moment = moments?.find((m) => m.moment_id === moment_id); + userXId = id; + } + + //Now if moment was found, navigate to the respective moment if (moment) { + if (notification_object?.parent_comment) { + dispatch(updateReplyPosted(notification_object)); + } navigation.push('IndividualMoment', { moment, - userXId: undefined, // we're only viewing our own moment here + userXId: userXId, // we're only viewing our own moment here screenType, }); setTimeout(() => { navigation.push('MomentCommentsScreen', { - moment_id: moment.moment_id, + moment_id: moment_id, screenType, + comment_id: comment_id, }); }, 500); } @@ -118,7 +172,9 @@ const Notification: React.FC<NotificationProps> = (props) => { }; const handleAcceptRequest = async () => { - await dispatch(acceptFriendRequest({id, username, first_name, last_name})); + await dispatch( + acceptFriendRequest({id, username, first_name, last_name, thumbnail_url}), + ); await dispatch(updateUserXFriends(id, state)); dispatch(loadUserNotifications()); }; @@ -137,8 +193,8 @@ const Notification: React.FC<NotificationProps> = (props) => { <Image style={styles.avatar} source={ - avatarURI - ? {uri: avatarURI, cache: 'only-if-cached'} + avatar + ? {uri: avatar} : require('../../assets/images/avatar-placeholder.png') } /> @@ -159,8 +215,8 @@ const Notification: React.FC<NotificationProps> = (props) => { </View> )} {notification_type === 'CMT' && notification_object && ( - <Image style={styles.moment} source={{uri: momentURI}} /> - )} + <Image style={styles.moment} source={{uri: momentURI}} /> + )} </TouchableWithoutFeedback> </> ); |