Skip to content

Commit 5269217

Browse files
committed
Merge branch 'dev-frontend' into feat/115
2 parents 695af2c + 2a3d3c8 commit 5269217

File tree

2 files changed

+85
-5
lines changed

2 files changed

+85
-5
lines changed

frontend/src/components/atoms/BlockContent/BlockContent.tsx

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
regex,
1616
fontSize,
1717
placeHolder,
18-
listComponent,
18+
listBlockType,
1919
} from '@utils/blockContent';
2020
import { useCommand, useManager } from '@/hooks';
2121
import { focusState } from '@/stores/page';
@@ -61,6 +61,7 @@ function BlockContent(blockDTO: Block) {
6161
const [blockMap, setBlockMap] = useRecoilState(blockMapState);
6262
const focusId = useRecoilValue(focusState);
6363
const caretRef = useRef(0);
64+
const listCnt = useRef(1);
6465
const [Dispatcher] = useCommand();
6566
const draggingBlock = useRecoilValue(draggingBlockState);
6667
const [{ blockIndex }] = useManager(blockDTO.id);
@@ -85,6 +86,33 @@ function BlockContent(blockDTO: Block) {
8586
selection.collapse(selection.focusNode, caretRef.current);
8687
}, [blockDTO.value]);
8788

89+
const indexInSibling: number = blockMap[
90+
blockDTO.parentId
91+
].childIdList.findIndex((childId: string) => childId === blockDTO.id);
92+
93+
const upperBlocks: Array<Block> = blockMap[blockDTO.parentId].childIdList
94+
.map((childId: any) => blockMap[childId])
95+
.slice(0, indexInSibling)
96+
.reverse();
97+
98+
const isUpperBlockEqualToNumberList = (): boolean => {
99+
if (upperBlocks.length) {
100+
return upperBlocks[0].type === BlockType.NUMBERED_LIST;
101+
}
102+
return false;
103+
};
104+
105+
const cntOfUpperNumberListBlock = (): number => {
106+
let cnt = 0;
107+
for (const upperblock of upperBlocks) {
108+
if (upperblock.type !== BlockType.NUMBERED_LIST) break;
109+
cnt += 1;
110+
}
111+
return cnt;
112+
};
113+
114+
const FIRST_LIST_NUMBER = '1';
115+
88116
const handleBlock = (value: string, type?: BlockType) =>
89117
type
90118
? setBlockMap({
@@ -103,6 +131,19 @@ function BlockContent(blockDTO: Block) {
103131
);
104132

105133
if (newType) {
134+
if (newType[0] === BlockType.NUMBERED_LIST) {
135+
if (!indexInSibling && content[0] !== FIRST_LIST_NUMBER) return;
136+
if (indexInSibling) {
137+
const numberListUpperBlock = isUpperBlockEqualToNumberList();
138+
if (!numberListUpperBlock && content[0] !== FIRST_LIST_NUMBER) return;
139+
if (
140+
numberListUpperBlock &&
141+
cntOfUpperNumberListBlock() + 1 !== +content[0]
142+
)
143+
return;
144+
}
145+
}
146+
106147
handleBlock(
107148
content.slice(content.indexOf(' ') + 1, content.length),
108149
newType[0] as BlockType,
@@ -152,6 +193,37 @@ function BlockContent(blockDTO: Block) {
152193
}
153194
};
154195

196+
useEffect(() => {
197+
blockRefState[blockDTO.id] = contentEditableRef;
198+
return () => {
199+
blockRefState[blockDTO.id] = null;
200+
};
201+
}, []);
202+
203+
useEffect(() => {
204+
if (focusId === blockDTO.id) contentEditableRef.current.focus();
205+
}, [focusId]);
206+
207+
useEffect(() => {
208+
const selection = window.getSelection();
209+
const nodeLength = selection.focusNode?.nodeValue?.length ?? 0;
210+
if (caretRef.current > nodeLength) {
211+
caretRef.current = nodeLength;
212+
}
213+
selection.collapse(selection.focusNode, caretRef.current);
214+
215+
if (blockDTO.type === BlockType.NUMBERED_LIST) {
216+
const numberListUpperBlock = isUpperBlockEqualToNumberList();
217+
if (!indexInSibling || !numberListUpperBlock) {
218+
listCnt.current = 1;
219+
return;
220+
}
221+
if (numberListUpperBlock) {
222+
listCnt.current = cntOfUpperNumberListBlock() + 1;
223+
}
224+
}
225+
}, [blockDTO.value]);
226+
155227
const dropDraggingBlockHandler = async () => {
156228
const blockId = draggingBlock?.id;
157229
if (!blockId || blockId === blockDTO.id) {
@@ -174,7 +246,7 @@ function BlockContent(blockDTO: Block) {
174246

175247
return (
176248
<div css={blockContentCSS} onMouseUp={dropDraggingBlockHandler}>
177-
{listComponent[blockDTO.type]}
249+
{listBlockType(blockDTO, listCnt.current)}
178250
<div
179251
ref={contentEditableRef}
180252
css={editableDivCSS(blockDTO)}

frontend/src/utils/blockContent.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
/** @jsx jsx */
22
/** @jsxRuntime classic */
3-
import { jsx } from '@emotion/react';
3+
import { jsx, css } from '@emotion/react';
4+
5+
import { Block, BlockType } from '@/schemes';
46
import { ReactComponent as Toggle } from '@assets/toggle-default.svg';
57

68
export const regex: { [key: string]: RegExp } = {
79
heading1: /^#\s[^\s.]*/gm,
810
heading2: /^##\s[^\s.]*/gm,
911
heading3: /^###\s[^\s.]*/gm,
1012
bulletedlist: /^-\s[^\s.]*/gm,
11-
numberedlist: /^1.\s[^\s.]*/gm,
13+
numberedlist: /^\d.\s[^\s.]*/gm,
1214
togglelist: /^>\s[^\s.]*/gm,
1315
quote: /^\|\s[^\s.]*/gm,
1416
};
1517

18+
export const listBlockType = (block: Block, idx: number) => {
19+
if (block.type === BlockType.NUMBERED_LIST) {
20+
return <span>{`${idx}. `}</span>;
21+
}
22+
return listComponent[block.type];
23+
};
24+
1625
const divCSS = css`
1726
margin: 0px 4px;
1827
font-size: 18px;
@@ -22,7 +31,6 @@ const divCSS = css`
2231

2332
export const listComponent: { [key: string]: any } = {
2433
bulletedlist: <div css={divCSS}></div>,
25-
numberedlist: <div css={divCSS}> 1. </div>,
2634
togglelist: (
2735
<div css={divCSS}>
2836
<Toggle />

0 commit comments

Comments
 (0)