Shun Miyazawa 2 лет назад
Родитель
Сommit
730584ddbe

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

@@ -172,6 +172,8 @@ type Props = CommonProps & {
   skipSSR: boolean,
   skipSSR: boolean,
   ssrMaxRevisionBodyLength: number,
   ssrMaxRevisionBodyLength: number,
 
 
+  hasYjsDraft: boolean,
+
   grantData?: IPageGrantData,
   grantData?: IPageGrantData,
 
 
   rendererConfig: RendererConfig,
   rendererConfig: RendererConfig,
@@ -525,6 +527,8 @@ async function injectRoutingInformation(context: GetServerSidePropsContext, prop
         props.currentPathname = `/${page._id}`;
         props.currentPathname = `/${page._id}`;
       }
       }
     }
     }
+
+    props.hasYjsDraft = crowi.pageService.hasYjsDraft(page._id);
   }
   }
 }
 }
 
 

+ 7 - 0
apps/app/src/server/service/page/index.ts

@@ -40,6 +40,7 @@ import {
 import type { PageTagRelationDocument } from '~/server/models/page-tag-relation';
 import type { PageTagRelationDocument } from '~/server/models/page-tag-relation';
 import PageTagRelation from '~/server/models/page-tag-relation';
 import PageTagRelation from '~/server/models/page-tag-relation';
 import type { UserGroupDocument } from '~/server/models/user-group';
 import type { UserGroupDocument } from '~/server/models/user-group';
+import { getYjsConnectionManager } from '~/server/service/yjs-connection-manager';
 import { createBatchStream } from '~/server/util/batch-stream';
 import { createBatchStream } from '~/server/util/batch-stream';
 import { collectAncestorPaths } from '~/server/util/collect-ancestor-paths';
 import { collectAncestorPaths } from '~/server/util/collect-ancestor-paths';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
@@ -4437,6 +4438,12 @@ class PageService implements IPageService {
     });
     });
   }
   }
 
 
+  hasYjsDraft(pageId: string): boolean {
+    const yjsConnectionManager = getYjsConnectionManager();
+    const currentYdoc = yjsConnectionManager.getCurrentYdoc(pageId);
+    return currentYdoc != null;
+  }
+
   async createTtlIndex(): Promise<void> {
   async createTtlIndex(): Promise<void> {
     const wipPageExpirationSeconds = configManager.getConfig('crowi', 'app:wipPageExpirationSeconds') ?? 172800;
     const wipPageExpirationSeconds = configManager.getConfig('crowi', 'app:wipPageExpirationSeconds') ?? 172800;
     const collection = mongoose.connection.collection('pages');
     const collection = mongoose.connection.collection('pages');

+ 10 - 6
apps/app/src/server/service/yjs-connection-manager.ts

@@ -40,13 +40,16 @@ class YjsConnectionManager {
   }
   }
 
 
   public async handleYDocSync(pageId: string, initialValue: string): Promise<void> {
   public async handleYDocSync(pageId: string, initialValue: string): Promise<void> {
+    const currentYdoc = this.getCurrentYdoc(pageId);
+    if (currentYdoc == null) {
+      return;
+    }
+
     const persistedYdoc = await this.mdb.getYDoc(pageId);
     const persistedYdoc = await this.mdb.getYDoc(pageId);
     const persistedStateVector = Y.encodeStateVector(persistedYdoc);
     const persistedStateVector = Y.encodeStateVector(persistedYdoc);
 
 
     await this.mdb.flushDocument(pageId);
     await this.mdb.flushDocument(pageId);
 
 
-    const currentYdoc = this.getCurrentYdoc(pageId);
-
     const persistedCodeMirrorText = persistedYdoc.getText('codemirror').toString();
     const persistedCodeMirrorText = persistedYdoc.getText('codemirror').toString();
     const currentCodeMirrorText = currentYdoc.getText('codemirror').toString();
     const currentCodeMirrorText = currentYdoc.getText('codemirror').toString();
 
 
@@ -77,17 +80,18 @@ class YjsConnectionManager {
     // TODO: https://redmine.weseek.co.jp/issues/132775
     // TODO: https://redmine.weseek.co.jp/issues/132775
     // It's necessary to confirm that the user is not editing the target page in the Editor
     // It's necessary to confirm that the user is not editing the target page in the Editor
     const currentYdoc = this.getCurrentYdoc(pageId);
     const currentYdoc = this.getCurrentYdoc(pageId);
+    if (currentYdoc == null) {
+      return;
+    }
+
     const currentMarkdownLength = currentYdoc.getText('codemirror').length;
     const currentMarkdownLength = currentYdoc.getText('codemirror').length;
     currentYdoc.getText('codemirror').delete(0, currentMarkdownLength);
     currentYdoc.getText('codemirror').delete(0, currentMarkdownLength);
     currentYdoc.getText('codemirror').insert(0, newValue);
     currentYdoc.getText('codemirror').insert(0, newValue);
     Y.encodeStateAsUpdate(currentYdoc);
     Y.encodeStateAsUpdate(currentYdoc);
   }
   }
 
 
-  private getCurrentYdoc(pageId: string): Y.Doc {
+  public getCurrentYdoc(pageId: string): Y.Doc | undefined {
     const currentYdoc = this.ysocketio.documents.get(`yjs/${pageId}`);
     const currentYdoc = this.ysocketio.documents.get(`yjs/${pageId}`);
-    if (currentYdoc == null) {
-      throw new Error(`currentYdoc for pageId ${pageId} is undefined.`);
-    }
     return currentYdoc;
     return currentYdoc;
   }
   }