반응형
깃허브 데스크탑으로 프로젝트 관리하기 강의 오픈!! (인프런 바로가기)
참고
- GitHub OAuth Project Settings
- Material UI로 깃허브 로그인 프로필 만들기
- 깃허브 OAuth 콜백 처리하기
- 인증 토큰 획득 서버 구현하기
- 인증 토큰으로 로그인 상태 관리하기
- 로그인 정보를 활용하여 Commit Message 남기기
- 새 창으로 로그인해서 현재 상태 유지하기
Toast UI 에디터에서 깃허브 마크다운을 저장할 때,
RESTful API를 사용하기 위해 key와 owner를 고정시켰다.
따라서 해당 서비스가 배포되면, 누가 파일을 수정하고 있는지 알 수 없다.
const fileRead = async () => {
const octokit = new Octokit({
auth: myKey,
});
const result = await octokit.request(
`GET /repos/bloodstrawberry/${repo}/contents/${path}`,
{
owner: "bloodstrawberry",
...
}
);
return result;
};
리액트에 GitHub OAuth를 이용해 GitHub에 인증된 사용자만 편집하고, user ID를 commit 메시지에 남겨보자.
Project Settings
Toast UI Editor를 포함하여 아래의 코드에서 시작한다.
App.js
import React from "react";
import { Route, Link, Routes } from "react-router-dom";
import Home from "./page/Home";
import SimpleToastEditor from "./page/SimpleToastEditor";
import './App.css';
const App = () => {
return (
<div>
<div className="router">
<span>
<Link to="/">Home</Link>
</span>
<span>
<Link to="/editor">Toast UI Editor</Link>
</span>
</div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/editor" element={<SimpleToastEditor />} />
</Routes>
</div>
);
};
export default App;
page/Home.js
import React from "react";
import Box from "@mui/material/Box";
const Home = () => {
return (
<div>
<Box sx={{ m: 2 }}>
<h1>GitHub OAuth Test</h1>
</Box>
</div>
);
};
export default Home;
page/SimpleToastEditor.js
import React, { useEffect, useRef, useState } from "react";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
// GitHub RESTful API
import { Octokit } from "@octokit/rest";
// Toast UI Editor
import "@toast-ui/editor/dist/toastui-editor.css";
import "@toast-ui/editor/dist/toastui-editor-viewer.css"; // Viewer css
import { Editor } from "@toast-ui/react-editor";
import Viewer from "@toast-ui/editor/dist/toastui-editor-viewer";
// Dark Theme 적용
// import '@toast-ui/editor/dist/toastui-editor.css';
// import '@toast-ui/editor/dist/theme/toastui-editor-dark.css';
// Color Syntax Plugin
import "tui-color-picker/dist/tui-color-picker.css";
import "@toast-ui/editor-plugin-color-syntax/dist/toastui-editor-plugin-color-syntax.css";
import colorSyntax from "@toast-ui/editor-plugin-color-syntax";
// Table Merged Cell Plugin
import "@toast-ui/editor-plugin-table-merged-cell/dist/toastui-editor-plugin-table-merged-cell.css";
import tableMergedCell from "@toast-ui/editor-plugin-table-merged-cell";
const colorSyntaxOptions = {
preset: [
"#333333", "#666666", "#FFFFFF", "#EE2323", "#F89009", "#009A87", "#006DD7", "#8A3DB6",
"#781B33", "#5733B1", "#953B34", "#FFC1C8", "#FFC9AF", "#9FEEC3", "#99CEFA", "#C1BEF9",
],
};
//const CONTENT_KEY = "CONTENT_KEY";
let myKey = process.env.REACT_APP_MY_TOKEN;
const SimpleToastEditor = () => {
const editorRef = useRef(null);
const [editMode, setEditMode] = useState(false);
const repo = "auto-test";
const path = "README.md";
const getSHA = async (octokit) => {
const result = await octokit.request(
`GET /repos/bloodstrawberry/${repo}/contents/${path}`,
{
owner: "bloodstrawberry",
repo: `${repo}`,
path: `${path}`,
}
);
return result.data.sha;
};
const fileWrite = async (contents) => {
const octokit = new Octokit({
auth: myKey,
});
const currentSHA = await getSHA(octokit);
const result = await octokit.request(
`PUT /repos/bloodstrawberry/${repo}/contents/${path}`,
{
owner: "bloodstrawberry",
repo: `${repo}`,
path: `${path}`,
message: "commit message!",
sha: currentSHA,
committer: {
name: "bloodstrawberry",
email: "bloodstrawberry@github.com",
},
content: `${btoa(unescape(encodeURIComponent(`${contents}`)))}`,
headers: {
"X-GitHub-Api-Version": "2022-11-28",
},
}
);
console.log(result.status);
};
const fileRead = async () => {
const octokit = new Octokit({
auth: myKey,
});
const result = await octokit.request(
`GET /repos/bloodstrawberry/${repo}/contents/${path}`,
{
owner: "bloodstrawberry",
repo: `${repo}`,
path: `${path}`,
encoding: "utf-8",
decoding: "utf-8",
}
);
return result;
};
const handleSave = () => {
let markDownContent = editorRef.current.getInstance().getMarkdown();
//let htmlContent = editorRef.current.getInstance().getHTML();
console.log(markDownContent);
//localStorage.setItem(CONTENT_KEY, markDownContent);
fileWrite(markDownContent);
};
const initReadMe = async () => {
// let item = localStorage.getItem(CONTENT_KEY);
let result = await fileRead();
let contents = decodeURIComponent(escape(window.atob(result.data.content)));
//console.log(contents);
if (editMode === false) {
const viewer = new Viewer({
el: document.querySelector(".toast-editor-viewer"),
viewer: true,
height: "400px",
usageStatistics: false, // 통계 수집 거부
plugins: [tableMergedCell],
});
viewer.setMarkdown(contents);
}
if (editorRef.current)
editorRef.current.getInstance().setMarkdown(contents);
};
useEffect(() => {
initReadMe();
}, [editMode]);
return (
<div>
<Box sx={{ m: 2 }}>
<h1>Toast UI Editor</h1>
<Button
variant="outlined"
color="secondary"
sx={{ m: 1 }}
onClick={() => setEditMode(!editMode)}
>
{editMode ? "취소하기" : "편집하기"}
</Button>
<Button
variant="outlined"
color="primary"
sx={{ m: 1 }}
onClick={handleSave}
disabled={editMode === false}
>
저장하기
</Button>
{editMode === false && <div className="toast-editor-viewer"></div>}
{editMode === true && (
<Editor
ref={editorRef}
// initialValue={initContents}
height="400px"
placeholder="Please Enter Text."
previewStyle="tab" // or vertical
initialEditType="wysiwyg" // or markdown
// hideModeSwitch={true} // 하단 숨기기
toolbarItems={[
// 툴바 옵션 설정
["heading", "bold", "italic", "strike"],
["hr", "quote"],
["ul", "ol", "task", "indent", "outdent"],
["table", /* "image", */ "link"],
["code", "codeblock"],
]}
//theme="dark"
//useCommandShortcut={false} // 키보드 입력 컨트롤 방지 ex ctrl z 등
usageStatistics={false} // 통계 수집 거부
plugins={[[colorSyntax, colorSyntaxOptions], tableMergedCell]}
/>
)}
</Box>
</div>
);
};
export default SimpleToastEditor;
App.css
.router > span {
margin: 10px;
}
.router {
margin-bottom: 20px;
}
아래와 같은 화면이 나오면 Project Settings가 완성된다.
반응형
'개발 > React' 카테고리의 다른 글
리액트 - 깃허브 OAuth 콜백 처리하기 (GitHub OAuth Callback) (0) | 2023.08.19 |
---|---|
리액트 - Material UI로 깃허브 로그인 프로필 만들기 (0) | 2023.08.19 |
리액트 - .env 환경 변수 파일 관리하기 (0) | 2023.08.15 |
리액트 - Toast UI 에디터로 깃허브 마크다운 저장하기 (Toast UI Editor with GitHub RESTful API) (0) | 2023.07.30 |
리액트 - Toast UI 에디터 저장하고 초기화하기 (Save and Initialize Toast UI Editor) (0) | 2023.07.30 |
댓글