PageModelNotification.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import type { FC } from 'react';
  2. import React, { useCallback } from 'react';
  3. import type { IPage, HasObjectId } from '@growi/core';
  4. import { useRouter } from 'next/router';
  5. import { SupportedTargetModel } from '~/interfaces/activity';
  6. import type { IInAppNotification } from '~/interfaces/in-app-notification';
  7. import * as pageSerializers from '~/models/serializers/in-app-notification-snapshot/page';
  8. import { ModelNotification } from './ModelNotification';
  9. import { useActionMsgAndIconForModelNotification } from './useActionAndMsg';
  10. export interface ModelNotificationUtils {
  11. Notification: FC
  12. publishOpen: () => void
  13. }
  14. export const usePageModelNotification = (notification: IInAppNotification & HasObjectId): ModelNotificationUtils | null => {
  15. const router = useRouter();
  16. const { actionMsg, actionIcon } = useActionMsgAndIconForModelNotification(notification);
  17. const getActionUsers = useCallback(() => {
  18. const latestActionUsers = notification.actionUsers.slice(0, 3);
  19. const latestUsers = latestActionUsers.map((user) => {
  20. return `@${user.name}`;
  21. });
  22. let actionedUsers = '';
  23. const latestUsersCount = latestUsers.length;
  24. if (latestUsersCount === 1) {
  25. actionedUsers = latestUsers[0];
  26. }
  27. else if (notification.actionUsers.length >= 4) {
  28. actionedUsers = `${latestUsers.slice(0, 2).join(', ')} and ${notification.actionUsers.length - 2} others`;
  29. }
  30. else {
  31. actionedUsers = latestUsers.join(', ');
  32. }
  33. return actionedUsers;
  34. }, [notification.actionUsers]);
  35. const isPageModelNotification = (notification: IInAppNotification & HasObjectId): notification is IInAppNotification<IPage> & HasObjectId => {
  36. return notification.targetModel === SupportedTargetModel.MODEL_PAGE;
  37. };
  38. if (!isPageModelNotification(notification)) {
  39. return null;
  40. }
  41. const actionUsers = getActionUsers();
  42. notification.parsedSnapshot = pageSerializers.parseSnapshot(notification.snapshot);
  43. const Notification = () => {
  44. return (
  45. <ModelNotification
  46. notification={notification}
  47. actionMsg={actionMsg}
  48. actionIcon={actionIcon}
  49. actionUsers={actionUsers}
  50. />
  51. );
  52. };
  53. const publishOpen = () => {
  54. if (notification.target != null) {
  55. // jump to target page
  56. const targetPagePath = (notification.target as IPage).path;
  57. if (targetPagePath != null) {
  58. router.push(targetPagePath);
  59. }
  60. }
  61. };
  62. return {
  63. Notification,
  64. publishOpen,
  65. };
  66. };