import { FlatList, TouchableOpacity, View, Text, TextStyle, StyleSheet, ActivityIndicator, } from 'react-native'; import React, { useState } from 'react'; import { Events } from '@trycourier/client-graphql'; import { useUnreadNotifications } from '../../context/UnreadNotificationsContext'; import { useAllNotifications } from '../../context/AllNotificationsContext'; import type { MessageType, TrackingIds, } from '../../hooks/useMessage/MessagesStore/Messagestypes'; import { DIVIDER_COLOR, GRAY, LIGHT_GRAY } from '../../constants/colors'; import { useBrand, useReactNativeCourier, } from '../../context/CourierReactNativeProvider'; import { Message, FullScreenIndicator, BottomModal, BottomModalOption, } from '../../components'; import { BOLD } from '../../constants/fontSize'; const styles = StyleSheet.create({ emptyTextContainer: { flexGrow: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', }, textStyle: { fontWeight: BOLD, }, infiniteScrollLoaderContainer: { marginBottom: 6, padding: 16, }, bottomMenuContainer: { alignItems: 'center', justifyContent: 'center', backgroundColor: LIGHT_GRAY, borderTopLeftRadius: 10, borderTopRightRadius: 10, overflow: 'hidden', }, additionalMessageActionContainer: { paddingTop: 20, paddingBottom: 10, borderBottomColor: DIVIDER_COLOR, borderBottomWidth: 1, flexGrow: 1, flexDirection: 'row', width: '100%', justifyContent: 'center', alignItems: 'center', }, bottomModalOptionContainer: { width: '100%', alignItems: 'center', justifyContent: 'center', }, additionalActionTextStyle: { color: GRAY, fontSize: 10, }, }); type PropType = { notifications: MessageType[]; onMessageClick?: (_m: MessageType) => void; fetchMoreNotifications: () => void; isLoading: boolean; }; function NotificationList({ notifications, onMessageClick, fetchMoreNotifications, isLoading, }: PropType) { const [selectedMessage, setSelectedMessage] = useState< MessageType | undefined >(); const [isBottomModalOpen, setIsBottomModalOpen] = useState(false); const openBottomModal = () => setIsBottomModalOpen(true); const hideBottomModal = () => setIsBottomModalOpen(false); const { courierClient } = useReactNativeCourier(); const { trackEvent } = Events({ client: courierClient }); const { unreadNotifications, setUnreadNotifications, setUnreadNotificationsCount, } = useUnreadNotifications(); const { allNotifications, setAllNotifications } = useAllNotifications(); const closeBottomModal = () => { setIsBottomModalOpen(false); }; const handleMessageSelection = (message: MessageType) => { setSelectedMessage(message); openBottomModal(); }; let textColor = '#fff'; let emptyText = 'No Message Found'; const { emptyState } = useBrand(); if (emptyState?.textColor) { textColor = emptyState.textColor; } if (emptyState?.text) { emptyText = emptyState.text; } const emptyTextStyle: TextStyle = { ...styles.textStyle, color: textColor, }; const handleUnreadMessageUpdate = ({ selectedMessage: currentSelectedMessage, isMarkingRead, }: { selectedMessage: MessageType; isMarkingRead: boolean; }) => { let updatedUnreadNotifications: MessageType[] = [...unreadNotifications]; if (isMarkingRead) { updatedUnreadNotifications = unreadNotifications.filter( (notification) => notification.id !== currentSelectedMessage.id ); setUnreadNotificationsCount((prev) => prev - 1); } else { updatedUnreadNotifications = [ { ...currentSelectedMessage, read: false }, ...unreadNotifications, ]; setUnreadNotificationsCount((prev) => prev + 1); } setUnreadNotifications(updatedUnreadNotifications); }; const toggleAllMessageCategoryStatus = ({ selectedMessage: currentSelectedMessage, }: { selectedMessage: MessageType; }) => { const updatedAllNotifications = allNotifications.map((notification) => { if (notification.id === currentSelectedMessage.id) { return { ...notification, read: !notification.read }; } return notification; }); setAllNotifications(updatedAllNotifications); }; const genericReadUnreadEvent = ({ key }: { key: keyof TrackingIds }) => async () => { if (typeof selectedMessage === 'undefined') { return Promise.reject(); } const selectedTrackingId = selectedMessage.content.trackingIds[key]; if (typeof selectedTrackingId === 'undefined') return Promise.reject(); try { await trackEvent(selectedTrackingId); if (key === 'readTrackingId') { //* handle read event handleUnreadMessageUpdate({ selectedMessage, isMarkingRead: true }); } else if (key === 'unreadTrackingId') { //* handle unread event handleUnreadMessageUpdate({ selectedMessage, isMarkingRead: false }); } //* handle all message status toggleAllMessageCategoryStatus({ selectedMessage }); return Promise.resolve({ success: true }); } catch (e) { console.error({ e }); return Promise.reject(); } finally { hideBottomModal(); } }; const markAsReadEvent = genericReadUnreadEvent({ key: 'readTrackingId', }); const markAsUnreadEvent = genericReadUnreadEvent({ key: 'unreadTrackingId', }); if (notifications.length === 0 && isLoading) return ; if (notifications.length === 0 && isLoading === false) { return ( {emptyText} ); } return ( <> { return ( <> onMessageClick(item) : () => {} } > { if (item.read) return; handleUnreadMessageUpdate({ selectedMessage: item, isMarkingRead: true, }); toggleAllMessageCategoryStatus({ selectedMessage: item }); }} isFirst={index === 0} /> {index === notifications.length - 1 && isLoading && ( )} ); }} keyExtractor={({ id }) => id} onEndReached={fetchMoreNotifications} onEndReachedThreshold={0.01} showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false} /> {typeof selectedMessage !== 'undefined' && ( <> Additional Message Actions {selectedMessage.read ? ( ) : ( )} )} ); } export default NotificationList; NotificationList.defaultProps = { onMessageClick: undefined, };