InAppNotificationElm.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import type { FC } from 'react';
  2. import React from 'react';
  3. import type { HasObjectId } from '@growi/core';
  4. import { UserPicture } from '@growi/ui/dist/components';
  5. import { apiv3Post } from '~/client/util/apiv3-client';
  6. import type { IInAppNotification } from '~/interfaces/in-app-notification';
  7. import { InAppNotificationStatuses } from '~/interfaces/in-app-notification';
  8. import { useSWRxInAppNotificationStatus } from '~/stores/in-app-notification';
  9. import { useModelNotification } from './PageNotification';
  10. interface Props {
  11. notification: IInAppNotification & HasObjectId
  12. onUnopenedNotificationOpend?: () => void,
  13. }
  14. const InAppNotificationElm: FC<Props> = (props: Props) => {
  15. const { notification, onUnopenedNotificationOpend } = props;
  16. const modelNotificationUtils = useModelNotification(notification);
  17. const Notification = modelNotificationUtils?.Notification;
  18. const publishOpen = modelNotificationUtils?.publishOpen;
  19. const { mutate: mutateNotificationCount } = useSWRxInAppNotificationStatus();
  20. if (Notification == null || publishOpen == null) {
  21. return <></>;
  22. }
  23. const clickHandler = async(notification: IInAppNotification & HasObjectId): Promise<void> => {
  24. if (notification.status === InAppNotificationStatuses.STATUS_UNREAD) {
  25. // set notification status "OPEND"
  26. await apiv3Post('/in-app-notification/open', { id: notification._id });
  27. onUnopenedNotificationOpend?.();
  28. mutateNotificationCount();
  29. }
  30. publishOpen();
  31. };
  32. const renderActionUserPictures = (): JSX.Element => {
  33. const actionUsers = notification.actionUsers;
  34. if (actionUsers.length < 1) {
  35. return <></>;
  36. }
  37. if (actionUsers.length === 1) {
  38. return <UserPicture user={actionUsers[0]} size="md" noTooltip />;
  39. }
  40. return (
  41. <div className="position-relative">
  42. <UserPicture user={actionUsers[0]} size="md" noTooltip />
  43. <div className="position-absolute" style={{ top: 10, left: 10 }}>
  44. <UserPicture user={actionUsers[1]} size="md" noTooltip />
  45. </div>
  46. </div>
  47. );
  48. };
  49. return (
  50. <div className="list-group-item list-group-item-action" onClick={() => clickHandler(notification)} style={{ cursor: 'pointer' }}>
  51. <div className="d-flex align-items-center">
  52. <span
  53. className={`${notification.status === InAppNotificationStatuses.STATUS_UNREAD
  54. ? 'grw-unopend-notification'
  55. : 'ms-2'
  56. } rounded-circle me-3`}
  57. >
  58. </span>
  59. {renderActionUserPictures()}
  60. <Notification />
  61. </div>
  62. </div>
  63. );
  64. };
  65. export default InAppNotificationElm;