3j-dev / vivid_web

[Software Maestro 13th] Frontend for VIVID
0 stars 0 forks source link

위지윅 에디터 관련 치명적 문제점 발생 #5

Closed pasly0920 closed 2 years ago

pasly0920 commented 2 years ago

https://studyforus.com/review/496712

https://intrepidgeeks.com/tutorial/react-wysiwyg-importer#17

위지윅 에디터 한글 관련 문제 발생

위지윅 에디터 재개발 필요

pasly0920 commented 2 years ago
Screen Shot 2022-08-02 at 12 27 03 AM
pasly0920 commented 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;
pasly0920 commented 2 years ago
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;
pasly0920 commented 2 years ago

draft 기반 소스 코드는 위와 같다.

pasly0920 commented 2 years ago

Froala로 대체

https://froala.com/wysiwyg-editor/

pasly0920 commented 2 years ago

Froala editor 2개 생성되는 오류

pasly0920 commented 2 years ago

Froala editor 2개 생성되는 오류

해결 React.strict mode로 인해 2번 렌더링 된 것으로 판단 prod 모드에서는 오류가 나지 않을 것으로 예상 이는 추후 확인

pasly0920 commented 2 years ago
Screen Shot 2022-08-02 at 7 37 35 PM