EditorHeader.tsx 2.34 KB
import React, { ChangeEvent } from "react";
import ToastEditor from "tui-image-editor";
// @ts-ignore
import { saveAs } from "file-saver";

import { SubmenuContext } from "context/Submenu";

import "./EditorHeader.scss";

// TODO: 버튼 노출 규칙 정리하기
// TODO: 다크모드/라이트모드에 따른 버튼 스타일 수정하기
// TODO: 다크모드 토글 버튼을 input 타입 checked로 변경하기

interface EditorHeaderProps {
  editor: ToastEditor;
}

const rImageType = /data:(image\/.+);base64,/;

function base64ToBlob(data: any) {
  let mimeString = '';
  let raw, uInt8Array, i, rawLength;

  raw = data.replace(rImageType, function(header: string, imageType: string) {
    mimeString = imageType;
    return '';
  });

  raw = atob(raw);
  rawLength = raw.length;
  uInt8Array = new Uint8Array(rawLength); // eslint-disable-line

  for (i = 0; i < rawLength; i += 1) {
    uInt8Array[i] = raw.charCodeAt(i);
  }

  return new Blob([uInt8Array], {type: mimeString});
}

function EditorHeader({ editor }: EditorHeaderProps) {
  function onLoadImage(e: ChangeEvent<HTMLInputElement>): void {
    const { files }  = e.target;
    if (files) {
      editor.loadImageFromFile(files[0])
        .then((result: any) => console.log(result));
    }
  }

  function onSaveImage() {
    let imageName = editor.getImageName();
    const dataURL = editor.toDataURL();

    const blob = base64ToBlob(dataURL);
    const type = blob.type.split('/')[1];
    if (imageName.split('.').pop() !== type) {
      imageName += '.' + type;
    }
    saveAs(blob, imageName);
  }

  return (
    <div className="my-header">
      <SubmenuContext.Consumer>
        {({ visible, onChange }) => {
          return (
            <button className={`submenu-toggle ${visible && "activate"}`} onClick={() => onChange()}>
              <i className="fas fa-list" />
            </button>
          );
        }}
      </SubmenuContext.Consumer>

      <button onClick={onSaveImage}><i className="fas fa-save" /></button>
      <span className="file-box">
        <button><label htmlFor="input-image-file" className="file-box-button">
          <i className="fas fa-upload" />
        </label></button>
        <input type="file" accept="image/*" id="input-image-file" onChange={(e: ChangeEvent<HTMLInputElement>) => onLoadImage(e)}/>
      </span>
    </div>
  );
}

export default EditorHeader;