aboutsummaryrefslogtreecommitdiff
path: root/src/components/notifications/Notification.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/notifications/Notification.tsx')
-rw-r--r--src/components/notifications/Notification.tsx114
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>
</>
);