Преглед изворни кода

Use useCurrentPageYjsAwarenessStateSize

Shun Miyazawa пре 1 година
родитељ
комит
68459ad248

+ 27 - 5
apps/app/src/client/services/side-effects/yjs-draft.ts

@@ -4,15 +4,15 @@ import { useGlobalSocket } from '@growi/core/dist/swr';
 
 import type { CurrentPageYjsDraft } from '~/interfaces/page';
 import { SocketEventName } from '~/interfaces/websocket';
-import { useCurrentPageYjsDraft } from '~/stores/page';
+import { useCurrentPageYjsDraft, useCurrentPageYjsAwarenessStateSize } from '~/stores/page';
 
 export const useYjsDraftEffect = (): void => {
-  const { mutate: mutateeCurrentPageYjsDraft } = useCurrentPageYjsDraft();
   const { data: socket } = useGlobalSocket();
+  const { mutate: mutateCurrentPageYjsDraft } = useCurrentPageYjsDraft();
 
   const yjsDraftUpdateHandler = useCallback(((currentPageYjsDraft: CurrentPageYjsDraft) => {
-    mutateeCurrentPageYjsDraft(currentPageYjsDraft);
-  }), [mutateeCurrentPageYjsDraft]);
+    mutateCurrentPageYjsDraft(currentPageYjsDraft);
+  }), [mutateCurrentPageYjsDraft]);
 
   useEffect(() => {
 
@@ -24,5 +24,27 @@ export const useYjsDraftEffect = (): void => {
       socket.off(SocketEventName.YjsUpdated, yjsDraftUpdateHandler);
     };
 
-  }, [mutateeCurrentPageYjsDraft, socket, yjsDraftUpdateHandler]);
+  }, [mutateCurrentPageYjsDraft, socket, yjsDraftUpdateHandler]);
+};
+
+export const useYjsAwarenessStateEffect = (): void => {
+  const { data: socket } = useGlobalSocket();
+  const { mutate: mutateCurrentPageYjsAwarenessStateSize } = useCurrentPageYjsAwarenessStateSize();
+
+  const yjsAwarenessStateUpdateHandler = useCallback(((awarenessStateSize: number) => {
+    mutateCurrentPageYjsAwarenessStateSize(awarenessStateSize);
+  }), [mutateCurrentPageYjsAwarenessStateSize]);
+
+  useEffect(() => {
+
+    if (socket == null) { return }
+
+    socket.on(SocketEventName.YjsAwarenessStateUpdated, yjsAwarenessStateUpdateHandler);
+
+    return () => {
+      socket.off(SocketEventName.YjsAwarenessStateUpdated, yjsAwarenessStateUpdateHandler);
+    };
+
+  }, [socket, yjsAwarenessStateUpdateHandler]);
+
 };

+ 10 - 3
apps/app/src/components/Navbar/PageEditorModeManager.tsx

@@ -1,11 +1,11 @@
-import React, { type ReactNode, useCallback } from 'react';
+import React, { type ReactNode, useCallback, useMemo } from 'react';
 
 import { Origin } from '@growi/core';
 import { useTranslation } from 'next-i18next';
 
 import { useCreatePageAndTransit } from '~/client/services/create-page';
 import { toastError } from '~/client/util/toastr';
-import { useIsNotFound, useCurrentPageYjsDraft } from '~/stores/page';
+import { useIsNotFound, useCurrentPageYjsDraft, useCurrentPageYjsAwarenessStateSize } from '~/stores/page';
 import { EditorMode, useEditorMode, useIsDeviceLargerThanMd } from '~/stores/ui';
 
 import { shouldCreateWipPage } from '../../utils/should-create-wip-page';
@@ -65,6 +65,7 @@ export const PageEditorModeManager = (props: Props): JSX.Element => {
   const { mutate: mutateEditorMode } = useEditorMode();
   const { data: isDeviceLargerThanMd } = useIsDeviceLargerThanMd();
   const { data: currentPageYjsDraft } = useCurrentPageYjsDraft();
+  const { data: currentPageYjsAwarenessStateSize } = useCurrentPageYjsAwarenessStateSize();
 
   const { isCreating, createAndTransit } = useCreatePageAndTransit();
 
@@ -87,6 +88,12 @@ export const PageEditorModeManager = (props: Props): JSX.Element => {
 
   const _isBtnDisabled = isCreating || isBtnDisabled;
 
+  const circleColor = useMemo(() => {
+    if (currentPageYjsAwarenessStateSize != null && currentPageYjsAwarenessStateSize > 0) {
+      return 'bg-primary';
+    }
+  }, [currentPageYjsAwarenessStateSize]);
+
   return (
     <>
       <div
@@ -113,7 +120,7 @@ export const PageEditorModeManager = (props: Props): JSX.Element => {
             onClick={editButtonClickedHandler}
           >
             <span className="material-symbols-outlined me-1 fs-5">edit_square</span>{t('Edit')}
-            { currentPageYjsDraft?.hasYjsDraft && <span className="position-absolute top-0 start-100 translate-middle p-1 bg-primary rounded-circle" />}
+            { circleColor != null && <span className={`position-absolute top-0 start-100 translate-middle p-1 rounded-circle ${circleColor}`} />}
           </PageEditorModeButton>
         )}
       </div>

+ 2 - 1
apps/app/src/components/Page/DisplaySwitcher.tsx

@@ -4,7 +4,7 @@ import dynamic from 'next/dynamic';
 
 import { useHashChangedEffect } from '~/client/services/side-effects/hash-changed';
 import { usePageUpdatedEffect } from '~/client/services/side-effects/page-updated';
-import { useYjsDraftEffect } from '~/client/services/side-effects/yjs-draft';
+import { useYjsDraftEffect, useYjsAwarenessStateEffect } from '~/client/services/side-effects/yjs-draft';
 import { useIsEditable } from '~/stores/context';
 import { useIsLatestRevision } from '~/stores/page';
 import { EditorMode, useEditorMode } from '~/stores/ui';
@@ -28,6 +28,7 @@ export const DisplaySwitcher = (props: Props): JSX.Element => {
   usePageUpdatedEffect();
   useHashChangedEffect();
   useYjsDraftEffect();
+  useYjsAwarenessStateEffect();
 
   return (
     <>

+ 4 - 1
apps/app/src/pages/[[...path]].page.tsx

@@ -43,7 +43,7 @@ import {
 } from '~/stores/context';
 import { useEditingMarkdown } from '~/stores/editor';
 import {
-  useSWRxCurrentPage, useSWRMUTxCurrentPage, useCurrentPageId, useCurrentPageYjsDraft,
+  useSWRxCurrentPage, useSWRMUTxCurrentPage, useCurrentPageId, useCurrentPageYjsDraft, useCurrentPageYjsAwarenessStateSize,
   useIsNotFound, useIsLatestRevision, useTemplateTagData, useTemplateBodyData,
 } from '~/stores/page';
 import { useRedirectFrom } from '~/stores/page-redirect';
@@ -173,6 +173,7 @@ type Props = CommonProps & {
   ssrMaxRevisionBodyLength: number,
 
   hasYjsDraft: boolean,
+  yjsAwarenessStateSize: number,
 
   rendererConfig: RendererConfig,
 };
@@ -225,6 +226,7 @@ const Page: NextPageWithLayout<Props> = (props: Props) => {
   useIsUploadEnabled(props.isUploadEnabled);
 
   useCurrentPageYjsDraft({ hasYjsDraft: props.hasYjsDraft });
+  useCurrentPageYjsAwarenessStateSize(props.yjsAwarenessStateSize);
 
   const { pageWithMeta } = props;
 
@@ -491,6 +493,7 @@ async function injectRoutingInformation(context: GetServerSidePropsContext, prop
     }
 
     props.hasYjsDraft = crowi.pageService.hasYjsDraft(page._id);
+    props.yjsAwarenessStateSize = crowi.pageService.getYjsAwarenessStateSize(page._id);
   }
 }