Project: ๐ฉcodefolio - Toast UI Editor ์ฌ์ง ์ ๋ก๋
๐ฏ๋ชฉ์ :
์๋ํฐ ๊ธฐ์กด์ ๋ฌธ์ ์ ๊ฐ์
(์ฌ์ง ์
๋ก๋ ์ ๋ทฐ์ด์์ ์ด๋ฏธ์ง๊ฐ string ํ์์ผ๋ก ์ถ๋ ฅ๋์ด์ง)
๊ฐ์ : image url๊ณผ file name์ผ๋ก ๋ณด์ฌ์ง ์ ์๋๋ก
** ์ต์ข ํ๋ก์ ํธ ๊ธฐ๊ฐ ๋งค์ฐ ๋ฐ์ ๊ด๊ณ๋ก ์ฐ์ ์ค์ ์ฝ๋๋ง ์ ์ด๋์์**
1. UI tag
<Editor
ref={editorRef}
initialValue={postContent ?? null}
previewStyle="vertical"
// previewHighlight={false}
height="600px"
initialEditType="markdown"
useCommandShortcut
toolbarItems={toolbarItems}
language="ko-KR"
plugins={[colorSyntax]}
hooks={{
// @ts-ignore
addImageBlobHook: addImage,
}}
onChange={() => handleOnEditorChange()}
/>
hooks ์ฌ์ฉํ์ฌ addImage ๋ผ๋ ํจ์๋ฅผ ์ปค์คํ ํ์ฌ ๋ง๋ค์ด ์ฃผ์๋ค.
2. addImage (์ด๋ฏธ์ง ์์ฑ ์ ์ฒด ๊ณผ์ )
const addImage = async (blob: File, dropImage: HookCallback) => {
const img = await compressImg(blob); // ์ด๋ฏธ์ง ์์ถ
if (!img) return;
const url = await uploadImage(img); // ์
๋ก๋๋ ์ด๋ฏธ์ง ์๋ฒ url
if (!url) return;
dropImage(url, `${blob.name}`); // ์๋ํฐ์ ์ด๋ฏธ์ง ์ถ๊ฐ
};
์ด๋ฏธ์ง ์ฌ์ด์ฆ๊ฐ ๋๋ฌด ํฌ๋ฉด ์๋ฌ ๋ฐ์ ์ํ๊ณผ, 1ํ์ฑ์ผ๋ก ๋ณด์ฌ์ค ๋ด์ฉ์ ์์๋ก ์๋ฒํต์ ํ๋ ๋ฐ์
๋ถ๋ด์ด ์๊ธฐ ๋๋ฌธ์ ์ด๋ฏธ์ง ์์ถ์ ํ๊ณ , url ์๋ ์๋ฒํต์ ์ด ๋ img๋ฅผ ๋ฐ๊ณ ์๋ค.
3. uploadImage (์ ๋ก๋)
// ์ด๋ฏธ์ง ์
๋ก๋
const uploadImage = async (blob: File) => {
try {
const imgPath = crypto.randomUUID();
await supabase.storage.from("post-image").upload(imgPath, blob);
// ์ด๋ฏธ์ง ์ฌ๋ฆฌ๊ธฐ
const urlResult = await supabase.storage
.from("post-image")
.getPublicUrl(imgPath);
return urlResult.data.publicUrl;
} catch (error) {
console.log(error);
return false;
}
};
ํด๋น ํจ์๋ ์๋ํฐ์์ ์ฌ์ฉํ๋ ์ฌ์ง์ supabase๋ฅผ ํ์ฉํ์ฌ
๋ฐ์ดํฐํํ๋ฅผ ์ ์ฅํด ์ค๋ค.
4. compressImg (์์ถ)
// ์ด๋ฏธ์ง ์์ถ
const compressImg = async (blob: File): Promise<File | void> => {
const options = {
maxSize: 1,
initialQuality: 0.55, // initial 0.7
};
const result = await imageCompression(blob, options)
.then((res) => res)
.catch((e) => console.log(e, "์์ถ ์๋ฌ"));
return result;
};
์ด๋ฏธ์ง๋ฅผ ์์ถํ๋ ค๋ฉด imageCompression์ด๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ import ํ ํ ์ฌ์ฉํด์ผ ํ๋ค.
5. handleOnEditorChange
const handleOnEditorChange = () => {
// ์ ํจ์ฑ ๊ฒ์ฌ
const editorText = editorRef.current?.getInstance().getMarkdown();
if (editorText === " " || editorText === "" || editorText === undefined) {
return;
}
// HTML ๋์ ์ Markdown์ผ๋ก ์ ์ฅํฉ๋๋ค.
setPostContent(editorText);
};
์ ํจ์ฑ ๊ฒ์ฌ๋ ํด๋น ์๋ํฐ๊ฐ ์๋ฌด๋ฐ ํ์ดํ ์์ด
posting ํ์ ๋๋ฅผ ์ก์์ค๋ค. ์ดํ ๋ฌธ์ ์๋ค๋ฉด state๋ก editorText๋ฅผ ์ ์กํ๋ค.