์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- ๋ฆฌ์กํธ
- NEXT
- JS
- trainning
- PROJECT
- ํ์ค
- ์๋ฌ
- ํ๋ก์ ํธ
- ํ๋ก ํธ์๋
- ๋ถํธ์บ ํ
- ์๊ณ ๋ฆฌ์ฆ
- ์จ๋ผ์ธ
- ๊ฐ๋ฐ์
- ํจ์
- rn
- wil
- ๋ณ์
- Firebase
- K-Digital
- JavaScript
- ๋ด์ผ๋ฐฐ์
- ์ฝ๋ฉ
- ์๋ฐ์คํฌ๋ฆฝํธ
- type
- API
- react
- ๋ด์ผ๋ฐฐ์์บ ํ
- ํ์
- native
- Redux
- Today
- Total
Frontend ๊ฐ๋ฐ์ - hyo.loui
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๋ฅผ ์ ์กํ๋ค.
'Project' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Project: ๐ฉcodefolio - toast ui Editor(codeSyntaxHighlightPlugin) ์ ์ฉ ์ค ์๋ฌ ๋ ธํธ (0) | 2023.02.22 |
---|---|
Project: ๐ฉcodefolio - recoil, supabase Auth (0) | 2023.02.16 |
Project: ๐ฉcodefolio - DropDown, PostTitle / as-is to-be : 1 (0) | 2023.02.12 |
Project: ๐ฉcodefolio - ESlint, prettierrc ์ค์ ํ๊ธฐ / as-is to-be : 2 (0) | 2023.02.10 |
Project: ๐ฉcodefolio - supabase API (0) | 2023.02.08 |