PrimaryItemForNotification.tsx 1.5 KB

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