diff options
Diffstat (limited to 'src/components/notifications/Notification.tsx')
-rw-r--r-- | src/components/notifications/Notification.tsx | 150 |
1 files changed, 150 insertions, 0 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; |