page-updated.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import { useCallback, useEffect } from 'react';
  2. import { SocketEventName } from '~/interfaces/websocket';
  3. import { useCurrentPageData, useFetchCurrentPage, useSetRemoteLatestPageData } from '~/states/page';
  4. import type { RemoteRevisionData } from '~/states/page';
  5. import { useGlobalSocket } from '~/states/socket-io';
  6. import { useEditorMode, EditorMode } from '~/states/ui/editor';
  7. import { usePageStatusAlertActions } from '~/states/ui/modal/page-status-alert';
  8. import { useSWRxPageInfo } from '~/stores/page';
  9. export const usePageUpdatedEffect = (): void => {
  10. const setRemoteLatestPageData = useSetRemoteLatestPageData();
  11. const socket = useGlobalSocket();
  12. const { editorMode } = useEditorMode();
  13. const currentPage = useCurrentPageData();
  14. const { fetchCurrentPage } = useFetchCurrentPage();
  15. const { open: openPageStatusAlert, close: closePageStatusAlert } = usePageStatusAlertActions();
  16. const { mutate: mutatePageInfo } = useSWRxPageInfo(currentPage?._id);
  17. const remotePageDataUpdateHandler = useCallback((data) => {
  18. // Set remote page data
  19. const { s2cMessagePageUpdated } = data;
  20. const remoteData: RemoteRevisionData = {
  21. remoteRevisionId: s2cMessagePageUpdated.revisionId,
  22. remoteRevisionBody: s2cMessagePageUpdated.revisionBody,
  23. remoteRevisionLastUpdateUser: s2cMessagePageUpdated.remoteLastUpdateUser,
  24. remoteRevisionLastUpdatedAt: s2cMessagePageUpdated.revisionUpdateAt,
  25. };
  26. if (currentPage?._id != null && currentPage._id === s2cMessagePageUpdated.pageId) {
  27. setRemoteLatestPageData(remoteData);
  28. // Update PageInfo cache
  29. mutatePageInfo();
  30. // Open PageStatusAlert
  31. const currentRevisionId = currentPage?.revision?._id;
  32. const remoteRevisionId = s2cMessagePageUpdated.revisionId;
  33. const isRevisionOutdated = (currentRevisionId != null || remoteRevisionId != null) && currentRevisionId !== remoteRevisionId;
  34. // !!CAUTION!! Timing of calling openPageStatusAlert may clash with components/PageEditor/conflict.tsx
  35. if (isRevisionOutdated && editorMode === EditorMode.View) {
  36. openPageStatusAlert({ hideEditorMode: EditorMode.Editor, onRefleshPage: () => fetchCurrentPage({ force: true }) });
  37. }
  38. // Clear cache
  39. if (!isRevisionOutdated) {
  40. closePageStatusAlert();
  41. }
  42. }
  43. // eslint-disable-next-line max-len
  44. }, [currentPage?._id, currentPage?.revision?._id, setRemoteLatestPageData, mutatePageInfo, editorMode, openPageStatusAlert, fetchCurrentPage, closePageStatusAlert]);
  45. // listen socket for someone updating this page
  46. useEffect(() => {
  47. if (socket == null) { return }
  48. socket.on(SocketEventName.PageUpdated, remotePageDataUpdateHandler);
  49. return () => {
  50. socket.off(SocketEventName.PageUpdated, remotePageDataUpdateHandler);
  51. };
  52. }, [remotePageDataUpdateHandler, socket]);
  53. };