2
0

PrimaryItemForNotification.tsx 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { memo, useCallback, useEffect } from 'react';
  2. import { apiv3Post } from '~/client/util/apiv3-client';
  3. import { SidebarContentsType } from '~/interfaces/ui';
  4. import { useSWRxInAppNotificationStatus } from '~/stores/in-app-notification';
  5. import { useDefaultSocket } from '~/stores/socket-io';
  6. import loggerFactory from '~/utils/logger';
  7. import { PrimaryItem, type Props } from '../SidebarNav/PrimaryItem';
  8. const logger = loggerFactory('growi:PrimaryItemsForNotification');
  9. type PrimaryItemForNotificationProps = Omit<Props, 'onClick' | 'label' | 'iconName' | 'contents' | 'badgeContents' >
  10. // TODO(after v7 release): https://redmine.weseek.co.jp/issues/138463
  11. export const PrimaryItemForNotification = memo((props: PrimaryItemForNotificationProps) => {
  12. const { sidebarMode, onHover } = props;
  13. const { data: socket } = useDefaultSocket();
  14. const { data: notificationCount, mutate: mutateNotificationCount } = useSWRxInAppNotificationStatus();
  15. const badgeContents = notificationCount != null && notificationCount > 0 ? notificationCount : undefined;
  16. const updateNotificationStatus = useCallback(async() => {
  17. try {
  18. await apiv3Post('/in-app-notification/read');
  19. mutateNotificationCount();
  20. }
  21. catch (err) {
  22. logger.error(err);
  23. }
  24. }, [mutateNotificationCount]);
  25. const itemHoverHandler = useCallback((contents: SidebarContentsType) => {
  26. onHover?.(contents);
  27. updateNotificationStatus();
  28. }, [onHover, updateNotificationStatus]);
  29. useEffect(() => {
  30. if (socket != null) {
  31. socket.on('notificationUpdated', () => {
  32. mutateNotificationCount();
  33. });
  34. // clean up
  35. return () => {
  36. socket.off('notificationUpdated');
  37. };
  38. }
  39. }, [mutateNotificationCount, socket]);
  40. return (
  41. <PrimaryItem
  42. sidebarMode={sidebarMode}
  43. contents={SidebarContentsType.NOTIFICATION}
  44. label="In-App Notification"
  45. iconName="notifications"
  46. badgeContents={badgeContents}
  47. onClick={updateNotificationStatus}
  48. onHover={itemHoverHandler}
  49. />
  50. );
  51. });