Skip to content

Commit 5238377

Browse files
authored
Merge pull request #320 from boostcampwm-2022/dev
Deploy: 5주차 주말 작업 배포
2 parents 716773b + 54d8ef6 commit 5238377

File tree

24 files changed

+479
-267
lines changed

24 files changed

+479
-267
lines changed

.github/workflows/ci.yml

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,47 +3,58 @@ name: ci
33
on:
44
workflow_dispatch:
55
pull_request:
6-
branches: [ dev ]
6+
branches: [dev]
77

88
jobs:
99
build:
1010
name: Build and test
1111
strategy:
1212
matrix:
13-
os: [ ubuntu-latest, windows-latest, macos-latest ]
14-
node-version: [ 16, 18 ]
13+
os: [ubuntu-latest, windows-latest, macos-latest]
14+
node-version: [16, 18]
1515

1616
runs-on: ${{ matrix.os }}
1717

1818
steps:
19-
- uses: actions/checkout@v3
20-
- name: Use node.js ${{ matrix.node-version }}
21-
uses: actions/setup-node@v3
22-
with:
23-
node-version: ${{ matrix.node-version }}
24-
- run: npm ci
25-
26-
- name: For client directory
27-
run: |
28-
cd client
29-
npm run build --if-present
30-
npm test --if-present
31-
32-
- name: Install coreutils for macOS
33-
shell: bash
34-
if: runner.os == 'macOS'
35-
run: |
36-
brew install coreutils
37-
alias timeout=gtimeout
38-
39-
- name: For server directory
40-
shell: bash
41-
env:
42-
BACKEND_LOGIN_KEY: ${{ secrets.DOTENV_VAULT_BACKEND_CI_LOGIN_KEY }}
43-
run: |
44-
cd server
45-
npm run build --if-present
46-
npm test --if-present
47-
npx dotenv-vault login "$BACKEND_LOGIN_KEY" > /dev/null
48-
npx dotenv-vault pull ci .env
49-
timeout --verbose 10 npx ts-node index.ts || { if [ $? -eq 124 ]; then (exit 0); else (exit $?); fi }
19+
- uses: actions/checkout@v3
20+
- name: Use node.js ${{ matrix.node-version }}
21+
uses: actions/setup-node@v3
22+
with:
23+
node-version: ${{ matrix.node-version }}
24+
25+
- name: Cache dependencies
26+
id: cache
27+
uses: actions/cache@v3
28+
if: runner.os != 'Windows'
29+
with:
30+
path: '**/node_modules'
31+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
32+
33+
- name: Install Dependencies
34+
if: steps.cache.outputs.cache-hit != 'true'
35+
run: npm ci
36+
37+
- name: For client directory
38+
run: |
39+
cd client
40+
npm run build --if-present
41+
npm test --if-present
42+
43+
- name: Install coreutils for macOS
44+
shell: bash
45+
if: runner.os == 'macOS'
46+
run: |
47+
brew install coreutils
48+
alias timeout=gtimeout
49+
50+
- name: For server directory
51+
shell: bash
52+
env:
53+
BACKEND_LOGIN_KEY: ${{ secrets.DOTENV_VAULT_BACKEND_CI_LOGIN_KEY }}
54+
run: |
55+
cd server
56+
npm run build --if-present
57+
npm test --if-present
58+
npx dotenv-vault login "$BACKEND_LOGIN_KEY" > /dev/null
59+
npx dotenv-vault pull ci .env
60+
timeout --verbose 10 npx ts-node index.ts || { if [ $? -eq 124 ]; then (exit 0); else (exit $?); fi }

@wabinar/constants/socket-message.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ export const MOM_EVENT = {
2323
};
2424

2525
export const BLOCK_EVENT = {
26-
INIT: 'init-block',
2726
LOAD_TYPE: 'load-type',
2827
UPDATE_TYPE: 'update-type',
28+
INIT_TEXT: 'init-text',
2929
INSERT_TEXT: 'insert-text',
3030
DELETE_TEXT: 'delete-text',
3131
UPDATE_TEXT: 'update-text',
32-
CREATE_VOTE: 'create-vote',
32+
REGISTER_VOTE: 'register-vote',
3333
UPDATE_VOTE: 'update-vote',
3434
END_VOTE: 'end-vote',
3535
FETCH_QUESTIONS: 'fetch-questions',

client/src/components/Block/TextBlock.tsx

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,23 @@ 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;
21+
isLocalTypeUpdate: boolean;
2122
registerRef: (arg: React.RefObject<HTMLElement>) => void;
2223
}
2324

2425
function TextBlock({
2526
id,
2627
index,
27-
onKeyDown,
28+
onHandleBlock,
2829
type,
2930
setType,
31+
isLocalTypeUpdate,
3032
registerRef,
3133
}: BlockProps) {
3234
const { momSocket: socket } = useSocketContext();
33-
const [isOpen, setIsOpen] = useState<boolean>(false);
3435

3536
const {
3637
syncCRDT,
@@ -43,9 +44,12 @@ function TextBlock({
4344

4445
const blockRef = useRef<HTMLParagraphElement>(null);
4546

46-
const { offsetRef, setOffset, clearOffset, offsetHandlers } =
47+
const { offsetRef, setOffset, clearOffset, onArrowKeyDown, offsetHandlers } =
4748
useOffset(blockRef);
4849

50+
const [isOpen, setIsOpen] = useState<boolean>(false);
51+
const onClose = () => setIsOpen(false);
52+
4953
// 리모트 연산 수행결과로 innerText 변경 시 커서의 위치 조정
5054
const updateCaretPosition = (updateOffset = 0) => {
5155
if (!blockRef.current || offsetRef.current === null) return;
@@ -110,27 +114,41 @@ function TextBlock({
110114

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

115-
socket.emit(BLOCK_EVENT.INIT, id);
116-
117-
ee.on(`${BLOCK_EVENT.INIT}-${id}`, onInitialize);
119+
ee.on(`${BLOCK_EVENT.INIT_TEXT}-${id}`, onInitialize);
118120
ee.on(`${BLOCK_EVENT.UPDATE_TEXT}-${id}`, onInitialize);
119121
ee.on(`${BLOCK_EVENT.INSERT_TEXT}-${id}`, onInsert);
120122
ee.on(`${BLOCK_EVENT.DELETE_TEXT}-${id}`, onDelete);
121123

122124
return () => {
123-
ee.off(`${BLOCK_EVENT.INIT}-${id}`, onInitialize);
125+
ee.off(`${BLOCK_EVENT.INIT_TEXT}-${id}`, onInitialize);
124126
ee.off(`${BLOCK_EVENT.UPDATE_TEXT}-${id}`, onInitialize);
125127
ee.off(`${BLOCK_EVENT.INSERT_TEXT}-${id}`, onInsert);
126128
ee.off(`${BLOCK_EVENT.DELETE_TEXT}-${id}`, onDelete);
127129
};
128130
}, []);
129131

132+
useEffect(() => {
133+
registerRef(blockRef);
134+
}, [index]);
135+
130136
useEffect(() => {
131137
updateCaretPosition();
132138
}, [isOpen]);
133139

140+
useEffect(() => {
141+
if (isLocalTypeUpdate && readCRDT().length) {
142+
const remoteDeletion = localDeleteCRDT(0);
143+
socket.emit(BLOCK_EVENT.DELETE_TEXT, id, remoteDeletion);
144+
145+
if (!blockRef.current) return;
146+
147+
blockRef.current.innerText = readCRDT();
148+
blockRef.current.focus();
149+
}
150+
}, [type]);
151+
134152
// 로컬에서 일어나는 작성 - 삽입과 삭제 연산
135153
const onInput: React.FormEventHandler = (e) => {
136154
setOffset();
@@ -205,18 +223,16 @@ function TextBlock({
205223
updateCaretPosition(pastedText.length);
206224
};
207225

208-
const onKeyDownComposite: React.KeyboardEventHandler<HTMLParagraphElement> = (
209-
e,
210-
) => {
211-
offsetHandlers.onKeyDown(e);
212-
onKeyDown(e);
226+
const onKeyDown: React.KeyboardEventHandler<HTMLParagraphElement> = (e) => {
227+
onArrowKeyDown(e);
228+
onHandleBlock(e);
213229
};
214230

215231
const commonHandlers = {
216232
onInput,
217233
onCompositionEnd,
218234
...offsetHandlers,
219-
onKeyDown: onKeyDownComposite,
235+
onKeyDown,
220236
onPaste,
221237
};
222238

@@ -236,14 +252,14 @@ function TextBlock({
236252
{
237253
ref: blockRef,
238254
'data-id': id,
239-
'date-index': index,
255+
'data-index': index,
240256
...commonHandlers,
241257
contentEditable: true,
242258
suppressContentEditableWarning: true,
243259
},
244260
readCRDT(),
245261
)}
246-
{isOpen && <BlockSelector onSelect={onSelect} />}
262+
{isOpen && <BlockSelector onClose={onClose} onSelect={onSelect} />}
247263
</>
248264
);
249265
}

0 commit comments

Comments
 (0)