import { BellIcon } from "@heroicons/react/24/outline";
import { NotificationFeedType } from "@hey/data/enums";
import {
type NotificationRequest,
NotificationType,
useNotificationsQuery
} from "@hey/indexer";
import { memo, useCallback, useEffect } from "react";
import { WindowVirtualizer } from "virtua";
import AccountActionExecutedNotification from "@/components/Notification/Type/AccountActionExecutedNotification";
import CommentNotification from "@/components/Notification/Type/CommentNotification";
import FollowNotification from "@/components/Notification/Type/FollowNotification";
import MentionNotification from "@/components/Notification/Type/MentionNotification";
import PostActionExecutedNotification from "@/components/Notification/Type/PostActionExecutedNotification";
import QuoteNotification from "@/components/Notification/Type/QuoteNotification";
import ReactionNotification from "@/components/Notification/Type/ReactionNotification";
import RepostNotification from "@/components/Notification/Type/RepostNotification";
import { Card, EmptyState, ErrorMessage } from "@/components/Shared/UI";
import cn from "@/helpers/cn";
import useLoadMoreOnIntersect from "@/hooks/useLoadMoreOnIntersect";
import { useNotificationStore } from "@/store/persisted/useNotificationStore";
import NotificationShimmer from "./Shimmer";
import TokenDistributedNotification from "./Type/TokenDistributedNotification";
const notificationComponentMap = {
AccountActionExecutedNotification,
CommentNotification,
FollowNotification,
MentionNotification,
PostActionExecutedNotification,
QuoteNotification,
ReactionNotification,
RepostNotification,
TokenDistributedNotification
};
interface ListProps {
feedType: string;
}
const List = ({ feedType }: ListProps) => {
const { setLastSeenNotificationId } = useNotificationStore();
const getNotificationType = useCallback(() => {
switch (feedType) {
case NotificationFeedType.All:
return;
case NotificationFeedType.Mentions:
return [NotificationType.Mentioned];
case NotificationFeedType.Comments:
return [NotificationType.Commented];
case NotificationFeedType.Likes:
return [NotificationType.Reacted];
case NotificationFeedType.PostActions:
return [NotificationType.ExecutedPostAction];
case NotificationFeedType.Rewards:
return [NotificationType.TokenDistributed];
default:
return;
}
}, [feedType]);
const request: NotificationRequest = {
filter: {
includeLowScore: false,
notificationTypes: getNotificationType()
}
};
const { data, error, fetchMore, loading } = useNotificationsQuery({
variables: { request }
});
const notifications = data?.notifications?.items;
const pageInfo = data?.notifications?.pageInfo;
const hasMore = !!pageInfo?.next;
useEffect(() => {
const firstNotification = notifications?.[0];
if (
!firstNotification ||
typeof firstNotification !== "object" ||
!("id" in firstNotification)
) {
return;
}
const firstId = firstNotification.id;
if (firstId) {
setLastSeenNotificationId(firstId);
}
}, [notifications, setLastSeenNotificationId]);
const handleEndReached = useCallback(async () => {
if (hasMore) {
await fetchMore({
variables: { request: { ...request, cursor: pageInfo?.next } }
});
}
}, [fetchMore, hasMore, pageInfo?.next, request]);
const loadMoreRef = useLoadMoreOnIntersect(handleEndReached);
if (loading) {
return (
);
}
if (error) {
return ;
}
if (!notifications?.length) {
return (
}
message="Inbox zero!"
/>
);
}
return (
{notifications.map((notification) => {
if (!("id" in notification)) {
return null;
}
const Component =
notificationComponentMap[
notification.__typename as keyof typeof notificationComponentMap
];
return (
{Component && }
);
})}
{hasMore && }
);
};
export default memo(List);