PrimaryItemForNotification.tsx 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  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. // TODO(after v7 release): https://redmine.weseek.co.jp/issues/138463
  8. export const PrimaryItemForNotification = memo((props: PrimaryItemForNotificationProps) => {
  9. const { sidebarMode, onHover } = props;
  10. const { data: socket } = useDefaultSocket();
  11. const { data: notificationCount, mutate: mutateNotificationCount } = useSWRxInAppNotificationStatus();
  12. const badgeContents = notificationCount != null && notificationCount > 0 ? notificationCount : undefined;
  13. const itemHoverHandler = useCallback((contents: SidebarContentsType) => {
  14. onHover?.(contents);
  15. }, [onHover]);
  16. useEffect(() => {
  17. if (socket != null) {
  18. socket.on('notificationUpdated', () => {
  19. mutateNotificationCount();
  20. });
  21. // clean up
  22. return () => {
  23. socket.off('notificationUpdated');
  24. };
  25. }
  26. }, [mutateNotificationCount, socket]);
  27. return (
  28. <PrimaryItem
  29. sidebarMode={sidebarMode}
  30. contents={SidebarContentsType.NOTIFICATION}
  31. label="In-App Notification"
  32. iconName="notifications"
  33. badgeContents={badgeContents}
  34. onHover={itemHoverHandler}
  35. />
  36. );
  37. });