Skip to content

Commit 1baf875

Browse files
committed
2 parents c67471e + cf902bf commit 1baf875

File tree

5 files changed

+43
-36
lines changed

5 files changed

+43
-36
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ jobs:
2525
- name: Cache dependencies
2626
id: cache
2727
uses: actions/cache@v3
28+
if: runner.os != 'Windows'
2829
with:
2930
path: '**/node_modules'
3031
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

client/src/components/Block/TextBlock.tsx

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import ee from '../Mom/EventEmitter';
1515
interface BlockProps {
1616
id: string;
1717
index: number;
18-
onKeyDown: React.KeyboardEventHandler;
18+
onHandleBlock: React.KeyboardEventHandler;
1919
type: BlockType;
2020
setType: (arg: BlockType) => void;
2121
registerRef: (arg: React.RefObject<HTMLElement>) => void;
@@ -24,7 +24,7 @@ interface BlockProps {
2424
function TextBlock({
2525
id,
2626
index,
27-
onKeyDown,
27+
onHandleBlock,
2828
type,
2929
setType,
3030
registerRef,
@@ -43,7 +43,7 @@ function TextBlock({
4343

4444
const blockRef = useRef<HTMLParagraphElement>(null);
4545

46-
const { offsetRef, setOffset, clearOffset, offsetHandlers } =
46+
const { offsetRef, setOffset, clearOffset, onArrowKeyDown, offsetHandlers } =
4747
useOffset(blockRef);
4848

4949
// 리모트 연산 수행결과로 innerText 변경 시 커서의 위치 조정
@@ -110,8 +110,6 @@ function TextBlock({
110110

111111
// crdt의 초기화와 소켓을 통해 전달받는 리모트 연산 처리
112112
useEffect(() => {
113-
registerRef(blockRef);
114-
115113
socket.emit(BLOCK_EVENT.INIT_TEXT, id);
116114

117115
ee.on(`${BLOCK_EVENT.INIT_TEXT}-${id}`, onInitialize);
@@ -127,6 +125,10 @@ function TextBlock({
127125
};
128126
}, []);
129127

128+
useEffect(() => {
129+
registerRef(blockRef);
130+
}, [index]);
131+
130132
useEffect(() => {
131133
updateCaretPosition();
132134
}, [isOpen]);
@@ -205,19 +207,23 @@ function TextBlock({
205207
updateCaretPosition(pastedText.length);
206208
};
207209

208-
const onKeyDownComposite: React.KeyboardEventHandler<HTMLParagraphElement> = (
209-
e,
210-
) => {
211-
offsetHandlers.onKeyDown(e);
212-
onKeyDown(e);
210+
const onKeyDown: React.KeyboardEventHandler<HTMLParagraphElement> = (e) => {
211+
onArrowKeyDown(e);
212+
onHandleBlock(e);
213+
};
214+
215+
const onBlur = () => {
216+
clearOffset();
217+
setIsOpen(false);
213218
};
214219

215220
const commonHandlers = {
216221
onInput,
217222
onCompositionEnd,
218223
...offsetHandlers,
219-
onKeyDown: onKeyDownComposite,
224+
onKeyDown,
220225
onPaste,
226+
onBlur,
221227
};
222228

223229
const BLOCK_TYPES = Object.values(BlockType)
@@ -236,7 +242,7 @@ function TextBlock({
236242
{
237243
ref: blockRef,
238244
'data-id': id,
239-
'date-index': index,
245+
'data-index': index,
240246
...commonHandlers,
241247
contentEditable: true,
242248
suppressContentEditableWarning: true,

client/src/components/Block/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ export enum BlockType {
1919
interface BlockProps {
2020
id: string;
2121
index: number;
22-
onKeyDown: React.KeyboardEventHandler;
22+
onHandleBlock: React.KeyboardEventHandler;
2323
registerRef: (arg: React.RefObject<HTMLElement>) => void;
2424
}
2525

26-
function Block({ id, index, onKeyDown, registerRef }: BlockProps) {
26+
function Block({ id, index, onHandleBlock, registerRef }: BlockProps) {
2727
const { momSocket: socket } = useSocketContext();
2828

2929
const [type, setType] = useState<BlockType>();
@@ -58,7 +58,7 @@ function Block({ id, index, onKeyDown, registerRef }: BlockProps) {
5858
<TextBlock
5959
id={id}
6060
index={index}
61-
onKeyDown={onKeyDown}
61+
onHandleBlock={onHandleBlock}
6262
type={type}
6363
setType={setBlockType}
6464
registerRef={registerRef}

client/src/components/Mom/index.tsx

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function Mom() {
2727
const titleRef = useRef<HTMLHeadingElement>(null);
2828

2929
const onTitleUpdate: React.FormEventHandler<HTMLHeadingElement> = useDebounce(
30-
(e) => {
30+
() => {
3131
if (!titleRef.current) return;
3232

3333
const title = titleRef.current.innerText;
@@ -46,13 +46,13 @@ function Mom() {
4646
focusIndex.current = idx;
4747
};
4848

49-
const setBlockFocus = () => {
49+
const setBlockFocus = (index: number) => {
5050
if (!blockRefs.current || focusIndex.current === undefined) return;
5151

5252
const idx = focusIndex.current;
53+
if (index === undefined || index !== idx) return;
5354

5455
const targetBlock = blockRefs.current[idx];
55-
5656
if (!targetBlock || !targetBlock.current) return;
5757

5858
targetBlock.current.focus();
@@ -71,7 +71,7 @@ function Mom() {
7171
range.collapse();
7272
};
7373

74-
const onKeyDown: React.KeyboardEventHandler = (e) => {
74+
const onHandleBlock: React.KeyboardEventHandler = (e) => {
7575
const target = e.target as HTMLParagraphElement;
7676

7777
const { index: indexString } = target.dataset;
@@ -104,17 +104,16 @@ function Mom() {
104104
updateBlockFocus(index - 1);
105105

106106
setBlocks(spreadCRDT());
107-
setBlockFocus();
107+
108+
if (focusIndex.current === undefined) return;
109+
setBlockFocus(focusIndex.current);
110+
108111
setCaretToEnd();
109112

110113
socket.emit(MOM_EVENT.DELETE_BLOCK, id, remoteDeletion);
111114
}
112115
};
113116

114-
useEffect(() => {
115-
setBlockFocus();
116-
}, [blocks]);
117-
118117
useEffect(() => {
119118
if (!selectedMom) return;
120119

@@ -184,6 +183,12 @@ function Mom() {
184183
};
185184
}, [selectedMom]);
186185

186+
const registerRef =
187+
(index: number) => (ref: React.RefObject<HTMLElement>) => {
188+
blockRefs.current[index] = ref;
189+
setBlockFocus(index);
190+
};
191+
187192
return selectedMom ? (
188193
<div className={style['mom-container']}>
189194
<div className={style['mom']}>
@@ -205,10 +210,8 @@ function Mom() {
205210
key={id}
206211
id={id}
207212
index={index}
208-
onKeyDown={onKeyDown}
209-
registerRef={(ref: React.RefObject<HTMLElement>) => {
210-
blockRefs.current[index] = ref;
211-
}}
213+
onHandleBlock={onHandleBlock}
214+
registerRef={registerRef(index)}
212215
/>
213216
))}
214217
</div>

client/src/hooks/useOffset.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function useOffset(blockRef: React.RefObject<HTMLParagraphElement>) {
2929
};
3030

3131
// keydown 이벤트는 키 입력의 내용 반영 이전에 발생
32-
const onKeyDown: React.KeyboardEventHandler = (e) => {
32+
const onArrowKeyDown: React.KeyboardEventHandler = (e) => {
3333
const ARROW_LEFT = 'ArrowLeft';
3434
const ARROW_RIGHT = 'ArrowRight';
3535

@@ -43,8 +43,8 @@ export function useOffset(blockRef: React.RefObject<HTMLParagraphElement>) {
4343
}
4444
};
4545

46-
// 위 아래 방향키 이동은 핸들링하지 않음
47-
const onKeyUp: React.KeyboardEventHandler = (e) => {
46+
// 위 아래 방향키 이동은 keyDown에서 핸들링하지 않음
47+
const onArrowKeyup: React.KeyboardEventHandler = (e) => {
4848
const ARROW_DOWN = 'ArrowDown';
4949
const ARROW_UP = 'ArrowUp';
5050

@@ -54,19 +54,16 @@ export function useOffset(blockRef: React.RefObject<HTMLParagraphElement>) {
5454
};
5555

5656
const offsetHandlers = {
57-
onFocus:
58-
setOffset as unknown as React.FocusEventHandler<HTMLParagraphElement>,
5957
onClick:
6058
setOffset as unknown as React.MouseEventHandler<HTMLParagraphElement>,
61-
onBlur: clearOffset,
62-
onKeyDown,
63-
onKeyUp,
59+
onKeyUp: onArrowKeyup,
6460
};
6561

6662
return {
6763
offsetRef,
6864
setOffset,
6965
clearOffset,
66+
onArrowKeyDown,
7067
offsetHandlers,
7168
};
7269
}

0 commit comments

Comments
 (0)