NotificationList.tsx

mail@pastecode.io avatar
unknown
typescript
13 days ago
3.9 kB
1
Indexable
Never
import { Icon, Text, Button, Spinner } from '@components';
import { NotificationHistory, TDeviceID } from '@models';
import { moderateScale } from '@utils';
import React, { FC, useState } from 'react';
import { SectionList, StyleSheet } from 'react-native';
import NotificationItem from './NotificationItem';
import { StylesFactoryProps, useStyles, useUpdateNotificationsHistory } from '@hooks';
import { ROUTES, useNavigation } from '@navigation';
import useLoadNotificationData from '../useLoadNotificationData';

type NotificationsListProps = {
  data: NotificationHistory[];
  currentPage: number;
  nextPage: (page: number) => void;
  isNotificationsLoading: boolean;
};

const NotificationsList: FC<NotificationsListProps> = ({ data, currentPage, nextPage, isNotificationsLoading }) => {
  const { styles, theme } = useStyles(stylesFactory);
  const [selectedNotification, setSelectedNotification] = useState<string[]>([]);
  const navigation = useNavigation();
  const { updateNotification } = useUpdateNotificationsHistory();
  const { groupedNotificationsArray, devicesData } = useLoadNotificationData(data);

  const handleDelete = () => {
    updateNotification({
      ids: selectedNotification,
      is_deleted: true,
    });
    setSelectedNotification([]);
  };

  const onLongPressHandler = (timestamp: string) => {
    // using timestamp because it is the only unique key for notification item
    setSelectedNotification(prevSelected => [...prevSelected, timestamp]);
  };

  const onPressHandler = (deviceId: TDeviceID, notification: Partial<NotificationHistory>) => {
    if (selectedNotification.length > 0) {
      if (selectedNotification.includes(notification.notification_create_time!)) {
        setSelectedNotification(prevSelected =>
          prevSelected.filter(item => item !== notification.notification_create_time),
        );
      } else {
        setSelectedNotification(prevSelected => [...prevSelected, notification.notification_create_time!]);
      }
    } else {
      updateNotification({
        ids: [notification.notification_create_time!],
        read: true,
      });
      if (notification.notification_type === 'motion_detect') {
        navigation.navigate(ROUTES.DisplayOfNotification, { deviceId });
      }
    }
  };

  const renderNotification = ({ item }: { item: NotificationHistory }) => (
    <NotificationItem
      item={item}
      longPressHandler={onLongPressHandler}
      pressHandler={onPressHandler}
      selected={selectedNotification.includes(item.notification_create_time)}
      deviceData={devicesData[item.device_id]}
    />
  );

  const renderDate = (date: string) => {
    return (
      <Text size={'medium'} style={{ paddingLeft: moderateScale(16), marginTop: moderateScale(16) }}>
        {date}
      </Text>
    );
  };

  return (
    <>
      <SectionList
        sections={groupedNotificationsArray}
        keyExtractor={(item, index) => item.device_id + index}
        renderItem={renderNotification}
        renderSectionHeader={({ section: { title } }) => renderDate(title)}
        onEndReached={() => nextPage(currentPage + 1)}
        onEndReachedThreshold={0.5}
        ListFooterComponent={<Spinner isVisible={isNotificationsLoading} />}
      />
      {selectedNotification.length > 0 && (
        <Button
          preset={'border'}
          style={styles.deleteBtn}
          color={theme.colors.controlBackground}
          onPress={handleDelete}
        >
          <Icon name={'delete'} color={theme.colors.white} />
          <Text color={theme.colors.white}>Delete</Text>
        </Button>
      )}
    </>
  );
};

export default NotificationsList;

const stylesFactory = ({ theme }: StylesFactoryProps) => {
  return StyleSheet.create({
    deleteBtn: {
      flexDirection: 'row',
      borderRadius: 0,
      borderRightWidth: 0,
      borderLeftWidth: 0,
      backgroundColor: theme.colors.bgCard,
    },
  });
};
Leave a Comment