Browse Source

Merge branch 'support/107699-next-PageStatusAlert' of https://github.com/weseek/growi into support/107699-next-PageStatusAlert

Yuken Tezuka 3 years ago
parent
commit
2aa41ebaec

+ 16 - 14
packages/app/_obsolete/src/client/services/PageContainer.js

@@ -277,12 +277,13 @@ export default class PageContainer extends Container {
     });
   }
 
-  // request to server so the client to join a room for each page
-  emitJoinPageRoomRequest() {
-    const socketIoContainer = this.appContainer.getContainer('SocketIoContainer');
-    const socket = socketIoContainer.getSocket();
-    socket.emit('join:page', { socketId: socket.id, pageId: this.state.pageId });
-  }
+  // replaced accompanied by omiting container: https://github.com/weseek/growi/pull/6968
+  // // request to server so the client to join a room for each page
+  // emitJoinPageRoomRequest() {
+  //   const socketIoContainer = this.appContainer.getContainer('SocketIoContainer');
+  //   const socket = socketIoContainer.getSocket();
+  //   socket.emit('join:page', { socketId: socket.id, pageId: this.state.pageId });
+  // }
 
   addWebSocketEventHandlers() {
     // eslint-disable-next-line @typescript-eslint/no-this-alias
@@ -300,15 +301,16 @@ export default class PageContainer extends Container {
       }
     });
 
-    socket.on('page:update', (data) => {
-      logger.debug({ obj: data }, `websocket on 'page:update'`); // eslint-disable-line quotes
+    // replaced accompanied by omiting container: https://github.com/weseek/growi/pull/6968
+    // socket.on('page:update', (data) => {
+    //   logger.debug({ obj: data }, `websocket on 'page:update'`); // eslint-disable-line quotes
 
-      // update remote page data
-      const { s2cMessagePageUpdated } = data;
-      if (s2cMessagePageUpdated.pageId === pageContainer.state.pageId) {
-        pageContainer.setLatestRemotePageData(s2cMessagePageUpdated);
-      }
-    });
+    //   // update remote page data
+    //   const { s2cMessagePageUpdated } = data;
+    //   if (s2cMessagePageUpdated.pageId === pageContainer.state.pageId) {
+    //     pageContainer.setLatestRemotePageData(s2cMessagePageUpdated);
+    //   }
+    // });
 
     socket.on('page:delete', (data) => {
       logger.debug({ obj: data }, `websocket on 'page:delete'`); // eslint-disable-line quotes

+ 16 - 1
packages/app/src/components/PageStatusAlert.tsx

@@ -1,11 +1,13 @@
-import React, { useCallback, useMemo } from 'react';
+import React, { useCallback, useEffect, useMemo } from 'react';
 
 import { useTranslation } from 'next-i18next';
 
+import { SocketEventName } from '~/interfaces/websocket';
 import {
   useHasDraftOnHackmd, useIsHackmdDraftUpdatingInRealtime, useRemoteRevisionId, useRevisionIdHackmdSynced,
 } from '~/stores/hackmd';
 import { useSWRxCurrentPage } from '~/stores/page';
+import { useGlobalSocket } from '~/stores/websocket';
 
 type AlertComponentContents = {
   additionalClasses: string[],
@@ -23,6 +25,19 @@ export const PageStatusAlert = (): JSX.Element => {
   const { data: pageData } = useSWRxCurrentPage();
   const revision = pageData?.revision;
 
+  const { data: socket } = useGlobalSocket();
+
+  useEffect(() => {
+    if (socket == null) { return }
+
+    socket.on(SocketEventName.PageUpdated, () => {
+      console.log('page updated');
+    });
+
+    return () => { socket.off(SocketEventName.PageUpdated) };
+
+  }, [socket]);
+
   const refreshPage = useCallback(() => {
     window.location.reload();
   }, []);

+ 5 - 0
packages/app/src/interfaces/websocket.ts

@@ -17,6 +17,11 @@ export const SocketEventName = {
   FinishAddPage: 'finishAddPage',
   RebuildingFailed: 'rebuildingFailed',
 
+  // Page Operation
+  PageCreated: 'page:create',
+  PageUpdated: 'page:update',
+  PageDeleted: 'page:delete',
+
 } as const;
 export type SocketEventName = typeof SocketEventName[keyof typeof SocketEventName];
 

+ 6 - 1
packages/app/src/pages/[[...path]].page.tsx

@@ -43,6 +43,7 @@ import {
   useEditorMode, useSelectedGrant,
   usePreferDrawerModeByUser, usePreferDrawerModeOnEditByUser, useSidebarCollapsed, useCurrentSidebarContents, useCurrentProductNavWidth,
 } from '~/stores/ui';
+import { useSetupGlobalSocket, useSetupGlobalSocketForPage } from '~/stores/websocket';
 import loggerFactory from '~/utils/logger';
 
 // import { isUserPage, isTrashPage, isSharedPage } from '~/utils/path-utils';
@@ -81,6 +82,7 @@ const GrowiSubNavigationSwitcher = dynamic(() => import('../components/Navbar/Gr
 const UsersHomePageFooter = dynamic<UsersHomePageFooterProps>(() => import('../components/UsersHomePageFooter')
   .then(mod => mod.UsersHomePageFooter), { ssr: false });
 const HandsontableModal = dynamic(() => import('../components/PageEditor/HandsontableModal').then(mod => mod.HandsontableModal), { ssr: false });
+const PageStatusAlert = dynamic(() => import('../components/PageStatusAlert').then(mod => mod.PageStatusAlert), { ssr: false });
 
 const logger = loggerFactory('growi:pages:all');
 
@@ -256,6 +258,9 @@ const GrowiPage: NextPage<Props> = (props: Props) => {
 
   const { getClassNamesByEditorMode } = useEditorMode();
 
+  useSetupGlobalSocket();
+  useSetupGlobalSocketForPage(pageId);
+
   const shouldRenderPutbackPageModal = pageWithMeta != null
     ? _isTrashPage(pageWithMeta.data.path)
     : false;
@@ -321,7 +326,7 @@ const GrowiPage: NextPage<Props> = (props: Props) => {
                     { props.isNotCreatablePage && <NotCreatablePage />}
                     { !props.isForbidden && !props.isNotCreatablePage && <DisplaySwitcher />}
                     {/* <DisplaySwitcher /> */}
-                    {/* <PageStatusAlert /> */}
+                    <PageStatusAlert />
                   </>
                 ) }
 

+ 28 - 9
packages/app/src/stores/websocket.tsx

@@ -1,9 +1,12 @@
-import { SWRResponse } from 'swr';
+import { useEffect } from 'react';
+
 import io, { Socket } from 'socket.io-client';
+import { SWRResponse } from 'swr';
 
-import { useStaticSWR } from './use-static-swr';
 import loggerFactory from '~/utils/logger';
 
+import { useStaticSWR } from './use-static-swr';
+
 const logger = loggerFactory('growi:stores:ui');
 
 export const GLOBAL_SOCKET_NS = '/';
@@ -15,15 +18,21 @@ export const GLOBAL_ADMIN_SOCKET_KEY = 'globalAdminSocket';
 /*
  * Global Socket
  */
-export const useSetupGlobalSocket = (): SWRResponse<Socket, Error> => {
-  const socket = io(GLOBAL_SOCKET_NS, {
-    transports: ['websocket'],
-  });
+export const useSetupGlobalSocket = (): void => {
+
+  const { mutate } = useStaticSWR(GLOBAL_SOCKET_KEY);
 
-  socket.on('error', (err) => { logger.error(err) });
-  socket.on('connect_error', (err) => { logger.error('Failed to connect with websocket.', err) });
+  useEffect(() => {
+    const socket = io(GLOBAL_SOCKET_NS, {
+      transports: ['websocket'],
+    });
 
-  return useStaticSWR(GLOBAL_SOCKET_KEY, socket);
+    socket.on('error', (err) => { logger.error(err) });
+    socket.on('connect_error', (err) => { logger.error('Failed to connect with websocket.', err) });
+
+    mutate(socket);
+
+  }, [mutate]);
 };
 
 export const useGlobalSocket = (): SWRResponse<Socket, Error> => {
@@ -51,3 +60,13 @@ export const useSetupGlobalAdminSocket = (shouldInit: boolean): SWRResponse<Sock
 export const useGlobalAdminSocket = (): SWRResponse<Socket, Error> => {
   return useStaticSWR(GLOBAL_ADMIN_SOCKET_KEY);
 };
+
+export const useSetupGlobalSocketForPage = (pageId: string | undefined): void => {
+  const { data: socket } = useGlobalSocket();
+
+  useEffect(() => {
+    if (socket == null || pageId == null) { return }
+
+    socket.emit('join:page', { socketId: socket.id, pageId });
+  }, [pageId, socket]);
+};