@@ -21,6 +21,7 @@ import { Node } from 'src/node/node.entity';
2121import { Edge } from 'src/edge/edge.entity' ;
2222import { YMapEdge } from './yjs.type' ;
2323import { RedisService } from '../redis/redis.service' ;
24+ import { PageNotFoundException } from 'src/exception/page.exception' ;
2425
2526// Y.Doc에는 name 컬럼이 없어서 생성했습니다.
2627class CustomDoc extends Y . Doc {
@@ -36,7 +37,7 @@ class CustomDoc extends Y.Doc {
3637export class YjsService
3738 implements OnGatewayInit , OnGatewayConnection , OnGatewayDisconnect
3839{
39- private logger = new Logger ( 'YjsGateway' ) ;
40+ private logger = new Logger ( YjsService . name ) ;
4041 private ysocketio : YSocketIO ;
4142
4243 constructor (
@@ -69,20 +70,41 @@ export class YjsService
6970 // document name이 flow-room이라면 모든 노드들을 볼 수 있는 화면입니다.
7071 // 노드를 클릭해 페이지를 열었을 때만 해당 페이지 값을 가져와서 초기 데이터로 세팅해줍니다.
7172 if ( customDoc . name ?. startsWith ( 'document-' ) ) {
72- const workspaceId = doc . guid ;
7373 const pageId = parseInt ( customDoc . name . split ( '-' ) [ 1 ] ) ;
74- const findPage = await this . pageService . findPageById ( pageId ) ;
74+
75+ // 초기 세팅할 page content
76+ let pageContent : JSON ;
77+ try {
78+ const findPage = await this . pageService . findPageById ( pageId ) ;
79+ pageContent = JSON . parse ( JSON . stringify ( findPage . content ) ) ;
80+ } catch ( exception ) {
81+ // 에러 스택 출력
82+ this . logger . error ( exception . stack ) ;
83+
84+ // 만약 존재하지 않는 페이지에 접근한다면 비어있는 content를 전달한다.
85+ if ( exception instanceof PageNotFoundException ) {
86+ pageContent = JSON . parse ( '{}' ) ;
87+ return ;
88+ }
89+
90+ throw exception ;
91+ }
7592
7693 // content가 비어있다면 내부 구조가 novel editor schema를 따르지 않기 때문에 오류가 납니다.
7794 // content가 존재할 때만 넣어줍니다.
78- const pageContent = JSON . parse ( JSON . stringify ( findPage . content ) ) ;
79- const novelEditorContent = {
80- type : 'doc' ,
81- content : pageContent ,
82- } ;
83- pageContent . length > 0 &&
84- // JSON.parse(findPage.content).length > 0 &&
85- this . initializePageContent ( novelEditorContent , editorDoc ) ;
95+ // const pageContent = JSON.parse(JSON.stringify(findPage.content));
96+ // const novelEditorContent = {
97+ // type: 'doc',
98+ // content: pageContent,
99+ // };
100+
101+ if ( Object . keys ( pageContent ) . length > 0 ) {
102+ this . transformText ( pageContent ) ;
103+ this . logger . error ( pageContent ) ;
104+ // this.logger.error(this.transformText(pageContent));
105+ this . initializePageContent ( pageContent , editorDoc ) ;
106+ }
107+ // JSON.parse(findPage.content).length > 0 &&
86108
87109 // 페이지 내용 변경 사항을 감지해서 데이터베이스에 갱신합니다.
88110 editorDoc . observeDeep ( ( ) => {
@@ -202,6 +224,10 @@ export class YjsService
202224 yTitleMap : Y . Map < unknown > ,
203225 yEmojiMap : Y . Map < unknown > ,
204226 ) : void {
227+ // 초기화
228+ yNodeMap . clear ( ) ;
229+ yTitleMap . clear ( ) ;
230+ yEmojiMap . clear ( ) ;
205231 nodes . forEach ( ( node ) => {
206232 const nodeId = node . id . toString ( ) ; // id를 string으로 변환
207233
@@ -256,14 +282,26 @@ export class YjsService
256282 }
257283
258284 // yXmlFragment에 content를 넣어준다.
259- initializePageContent ( content : unknown , yXmlFragment : Y . XmlFragment ) {
285+ initializePageContent ( content : JSON , yXmlFragment : Y . XmlFragment ) {
260286 prosemirrorJSONToYXmlFragment ( novelEditorSchema , content , yXmlFragment ) ;
261287 }
262288
263289 handleConnection ( ) {
264290 this . logger . log ( '접속' ) ;
265291 }
266292
293+ // editor에서 paragraph 내부 text 노드의 text 값의 빈 문자열을 제거한다.
294+ transformText ( doc : any ) {
295+ doc . content . forEach ( ( paragraph ) => {
296+ if ( paragraph . type === 'paragraph' && Array . isArray ( paragraph . content ) ) {
297+ paragraph . content . forEach ( ( textNode ) => {
298+ if ( textNode . type === 'text' && textNode . text === '' ) {
299+ textNode . text = ' ' ; // 빈 문자열을 "a"로 대체
300+ }
301+ } ) ;
302+ }
303+ } ) ;
304+ }
267305 handleDisconnect ( ) {
268306 this . logger . log ( '접속 해제' ) ;
269307 }
0 commit comments