Closed pasly0920 closed 2 years ago
import React, { useState, useRef } from 'react';
import { EditorState, DraftEditorCommand, RichUtils } from 'draft-js';
import Editor, { composeDecorators } from '@draft-js-plugins/editor';
import createImagePlugin from '@draft-js-plugins/image';
import createAlignmentPlugin from '@draft-js-plugins/alignment';
import createFocusPlugin from '@draft-js-plugins/focus';
import createResizeablePlugin from '@draft-js-plugins/resizeable';
import createBlockDndPlugin from '@draft-js-plugins/drag-n-drop';
import createDragNDropUploadPlugin from '@draft-js-plugins/drag-n-drop-upload';
import '@draft-js-plugins/alignment/lib/plugin.css';
import '@draft-js-plugins/focus/lib/plugin.css';
import '@draft-js-plugins/image/lib/plugin.css';
import { EditorContainer } from './style';
import noteImageUpload from '@/util/noteImageUpload';
const VideoStreamNote: React.FC = () => {
const [noteState, setNoteState] = useState<EditorState>(() => EditorState.createEmpty());
const editorRef = useRef<Editor>(null);
const handleKeyCommand = (command: DraftEditorCommand) => {
const newState = RichUtils.handleKeyCommand(noteState, command);
if (newState) {
setNoteState(newState);
return 'handled';
}
return 'not-handled';
};
const handleToggleClick = (e: React.MouseEvent, inlineStyle: string) => {
e.preventDefault();
setNoteState(RichUtils.toggleInlineStyle(noteState, inlineStyle));
};
const handleBlockClick = (e: React.MouseEvent, blockType: string) => {
e.preventDefault();
setNoteState(RichUtils.toggleBlockType(noteState, blockType));
};
const handleFocusEditor = () => {
editorRef.current?.focus();
};
const focusPlugin = createFocusPlugin();
const resizeablePlugin = createResizeablePlugin();
const blockDndPlugin = createBlockDndPlugin();
const alignmentPlugin = createAlignmentPlugin();
const { AlignmentTool } = alignmentPlugin;
const decorator = composeDecorators(
resizeablePlugin.decorator,
alignmentPlugin.decorator,
focusPlugin.decorator,
blockDndPlugin.decorator,
);
const imagePlugin = createImagePlugin({ decorator });
const dragNDropFileUploadPlugin = createDragNDropUploadPlugin({
handleUpload: noteImageUpload,
addImage: imagePlugin.addImage,
});
const plugins = [
dragNDropFileUploadPlugin,
blockDndPlugin,
focusPlugin,
alignmentPlugin,
resizeablePlugin,
imagePlugin,
];
return (
<EditorContainer onClick={handleFocusEditor}>
<div>
<button onMouseDown={(e) => handleBlockClick(e, 'header-one')}>h1</button>
<button onMouseDown={(e) => handleBlockClick(e, 'header-two')}>h2</button>
<button onMouseDown={(e) => handleBlockClick(e, 'header-three')}>h3</button>
<button onMouseDown={(e) => handleBlockClick(e, 'unstyled')}>normal</button>
<button onMouseDown={(e) => handleToggleClick(e, 'BOLD')}>bold</button>
<button onMouseDown={(e) => handleToggleClick(e, 'ITALIC')}>italic</button>
<button onMouseDown={(e) => handleToggleClick(e, 'STRIKETHROUGH')}>strikthrough</button>
<button onMouseDown={(e) => handleBlockClick(e, 'ordered-list-item')}>ol</button>
<button onMouseDown={(e) => handleBlockClick(e, 'unordered-list-item')}>ul</button>
<button
disabled={noteState.getUndoStack().size <= 0}
onMouseDown={() => setNoteState(EditorState.undo(noteState))}
>
undo
</button>
<button
disabled={noteState.getRedoStack().size <= 0}
onMouseDown={() => setNoteState(EditorState.redo(noteState))}
>
redo
</button>
</div>
<Editor
ref={editorRef}
editorState={noteState}
plugins={plugins}
onChange={setNoteState}
handleKeyCommand={handleKeyCommand}
/>
<AlignmentTool />
</EditorContainer>
);
};
export default VideoStreamNote;
const customUpload = (data, success, failed, progress) => {
console.log(data.files);
const mockResult = data.files.map((f) => ({
name: f.name,
src: 'https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3n2LI%2FbtrG3raAQAW%2F5bZRBHywhG0p3czfVEaH21%2Fimg.png',
}));
let intervalId = -1;
let currentProgress = 0;
intervalId = setInterval(() => {
console.log(currentProgress);
if (currentProgress < 100) {
currentProgress += 10;
progress(currentProgress, mockResult[0]);
}
if (currentProgress === 100) {
clearInterval(intervalId);
success(mockResult /*, { retainSrc: true }*/);
}
}, 100);
};
export default customUpload;
draft 기반 소스 코드는 위와 같다.
Froala로 대체
Froala editor 2개 생성되는 오류
Froala editor 2개 생성되는 오류
해결 React.strict mode로 인해 2번 렌더링 된 것으로 판단 prod 모드에서는 오류가 나지 않을 것으로 예상 이는 추후 확인
https://studyforus.com/review/496712
https://intrepidgeeks.com/tutorial/react-wysiwyg-importer#17
위지윅 에디터 한글 관련 문제 발생
위지윅 에디터 재개발 필요