PrimaryItemForNotification.tsx 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import { memo, useCallback, useEffect } from 'react';
  2. import { useSWRxNewsUnreadCount } from '~/features/news/client/hooks/use-news';
  3. import { SidebarContentsType } from '~/interfaces/ui';
  4. import { useGlobalSocket } from '~/states/socket-io';
  5. import { useSWRxInAppNotificationStatus } from '~/stores/in-app-notification';
  6. import { PrimaryItem, type PrimaryItemProps } from '../SidebarNav/PrimaryItem';
  7. type PrimaryItemForNotificationProps = Omit<
  8. PrimaryItemProps,
  9. 'onClick' | 'label' | 'iconName' | 'contents' | 'badgeContents'
  10. >;
  11. export const PrimaryItemForNotification = memo(
  12. (props: PrimaryItemForNotificationProps) => {
  13. const { sidebarMode, onHover } = props;
  14. const socket = useGlobalSocket();
  15. const { data: notificationCount, mutate: mutateNotificationCount } =
  16. useSWRxInAppNotificationStatus();
  17. const { data: newsUnreadCount } = useSWRxNewsUnreadCount();
  18. const totalUnread = (notificationCount ?? 0) + (newsUnreadCount ?? 0);
  19. const badgeContents = totalUnread > 0 ? totalUnread : undefined;
  20. const itemHoverHandler = useCallback(
  21. (contents: SidebarContentsType) => {
  22. onHover?.(contents);
  23. },
  24. [onHover],
  25. );
  26. useEffect(() => {
  27. if (socket != null) {
  28. socket.on('notificationUpdated', () => {
  29. mutateNotificationCount();
  30. });
  31. // clean up
  32. return () => {
  33. socket.off('notificationUpdated');
  34. };
  35. }
  36. }, [mutateNotificationCount, socket]);
  37. return (
  38. <PrimaryItem
  39. sidebarMode={sidebarMode}
  40. contents={SidebarContentsType.NOTIFICATION}
  41. label="In-App Notification"
  42. iconName="notifications"
  43. badgeContents={badgeContents}
  44. onHover={itemHoverHandler}
  45. />
  46. );
  47. },
  48. );