Skip to content

Commit

Permalink
Merge pull request #284 from BY-juun/master
Browse files Browse the repository at this point in the history
Refactor: image upload ν›…μœΌλ‘œ 좔상화, giscus attribute μƒμˆ˜ν™”
  • Loading branch information
june-by authored Nov 29, 2023
2 parents 96e2e0a + c93cbee commit 6c42812
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 160 deletions.
61 changes: 61 additions & 0 deletions client/Hooks/useImageUpload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { ServerURL } from "@constants";
import { useCallback, useState } from "react";

interface UploadImgResponse {
url: string;
uploaded: boolean;
}

interface Params {
onImageUploadSuccess?: (params: UploadImgResponse) => void;
}

const useImageUpload = (params?: Params) => {
const [uploadedImgSrc, setUploadedImgSrc] = useState<string | null>(null);

const handleClickUploadButton = useCallback(() => {
const inputElem = createInputElement();

document.body.appendChild(inputElem);

inputElem.click();

inputElem.onchange = async () => {
const file = inputElem.files;

if (!file) {
return;
}

const { url, uploaded } = await uploadImg(file[0]);
params?.onImageUploadSuccess?.({ url, uploaded });
setUploadedImgSrc(url);
document.body.removeChild(inputElem);
};
}, [params]);

return { uploadedImgSrc, setUploadedImgSrc, handleClickUploadButton };
};

const uploadImg = async (img: File) => {
const formData = new FormData();
formData.append("img", img);

const response = await fetch(`${ServerURL}/uploads`, {
method: "post",
body: formData,
});

return (await response.json()) as UploadImgResponse;
};

const createInputElement = () => {
const inputElem = document.createElement("input");
inputElem.setAttribute("type", "file");
inputElem.setAttribute("accept", "image/*");
inputElem.style.display = "none";
document.body.appendChild(inputElem);
return inputElem;
};

export default useImageUpload;
30 changes: 18 additions & 12 deletions client/components/post/PostComments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,12 @@ const Comments = () => {

const scriptElem = document.createElement("script");
scriptElem.src = `${src}/client.js`;
scriptElem.setAttribute("data-repo", "BY-juun/Blog");
scriptElem.setAttribute("data-repo-id", "MDEwOlJlcG9zaXRvcnkzODc4MTYxNjA=");
scriptElem.setAttribute("data-category", "Comments");
scriptElem.setAttribute("data-category-id", "DIC_kwDOFx2a4M4CYB9c");
scriptElem.setAttribute("data-mapping", "pathname");
scriptElem.setAttribute("data-reactions-enabled", "1");
scriptElem.setAttribute("data-emit-metadata", "0");
scriptElem.setAttribute("data-input-position", "bottom");

Object.entries(SCRIPT_ATTRIBUTES).forEach(([key, value]) => {
scriptElem.setAttribute(key, value);
});
scriptElem.setAttribute("data-theme", theme);
scriptElem.setAttribute("data-lang", "ko");
scriptElem.setAttribute("data-loading", "lazy");
scriptElem.setAttribute("crossorigin", "anonymous");
scriptElem.async = true;

commentWrapperRef.current?.appendChild(scriptElem);

return () => {
Expand All @@ -56,4 +48,18 @@ const Comments = () => {
return <section className={styles.PostComments} ref={commentWrapperRef} />;
};

const SCRIPT_ATTRIBUTES = {
"data-repo": "BY-juun/Blog",
"data-repo-id": "MDEwOlJlcG9zaXRvcnkzODc4MTYxNjA=",
"data-category": "Comments",
"data-category-id": "DIC_kwDOFx2a4M4CYB9c",
"data-mapping": "pathname",
"data-reactions-enabled": "1",
"data-emit-metadata": "0",
"data-input-position": "bottom",
"data-lang": "ko",
"data-loading": "lazy",
crossorigin: "anonymous",
};

export default Comments;
40 changes: 13 additions & 27 deletions client/components/shared/Form/Editor.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { type LegacyRef, useMemo, useRef } from "react";
import React, { type LegacyRef, useMemo, useRef, useCallback } from "react";
import dynamic from "next/dynamic";
import styles from "./styles.module.scss";
import "react-quill/dist/quill.snow.css";
Expand All @@ -7,6 +7,7 @@ import ReactQuill from "react-quill";
import Script from "next/script";
import "highlight.js/styles/atom-one-dark.css";
import { ServerURL } from "@constants";
import useImageUpload from "@hooks/useImageUpload";

interface EditorProps {
forwardedRef: LegacyRef<ReactQuill> | undefined;
Expand Down Expand Up @@ -34,33 +35,17 @@ const Editor = ({
}: Pick<EditorProps, "value" | "onChange">) => {
const QuillRef = useRef<ReactQuill>(null);

const imageHandler = () => {
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/*");
document.body.appendChild(input);
input.style.display = "none";
input.click();
input.onchange = async () => {
const file = input.files;
if (file !== null && QuillRef.current) {
const formData = new FormData();
formData.append("img", file[0]);
const onImageUploadSuccess = useCallback(({ url }: { url: string }) => {
if (!QuillRef.current) {
return;
}

const response = await fetch(`${ServerURL}/uploads`, {
method: "post",
body: formData,
});
const editor = QuillRef.current.getEditor();
const range = editor.getSelection();
editor.insertEmbed(Number(range?.index), "image", url);
}, []);

const data: { url: string; uploaded: boolean } = await response.json();

const img_url = data.url;
const editor = QuillRef.current.getEditor();
const range = editor.getSelection();
editor.insertEmbed(Number(range?.index), "image", img_url);
}
};
};
const { handleClickUploadButton } = useImageUpload({ onImageUploadSuccess });

const modules = useMemo(
() => ({
Expand All @@ -69,13 +54,14 @@ const Editor = ({
},
toolbar: {
container: containerConfig,
handlers: { image: imageHandler },
handlers: { image: handleClickUploadButton },
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false,
},
},
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);

Expand Down
33 changes: 16 additions & 17 deletions client/components/shared/Form/ImageUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, { useCallback, type ChangeEvent } from "react";
import ImageUploader from "@components/shared/ImageUploader";
import useImageUpload from "@hooks/useImageUpload";
import styles from "./styles.module.scss";
import Image from "next/image";

interface Props {
value?: string | null;
Expand All @@ -13,33 +15,30 @@ const PostFormImageUploader = ({ value, onChange }: Props) => {
},
[onChange]
);
const onImageUploadeSuccess = useCallback(
(imageUrl: string) => {
onChange(imageUrl);

const onImageUploadSuccess = useCallback(
({ url }: { url: string }) => {
onChange(url);
},
[onChange]
);

const { handleClickUploadButton } = useImageUpload({ onImageUploadSuccess });

return (
<ImageUploader>
<div className={styles.ImageUploader}>
<div>
<ImageUploader.ImageUrlInput
<input
placeholder="image url"
value={value ?? ""}
onChange={handleChangeImageUrlByInput}
/>
<ImageUploader.UploadButton
onUploadeSuccess={onImageUploadeSuccess}
text="썸넀일 μ„€μ •"
/>
<button type="button" onClick={handleClickUploadButton}>
썸넀일 μ„€μ •
</button>
</div>
<ImageUploader.Image
src={value as string}
alt="썸넀일"
width={300}
height={200}
/>
</ImageUploader>
{value && <Image src={value} alt="썸넀일" width={300} height={200} />}
</div>
);
};

Expand Down
22 changes: 22 additions & 0 deletions client/components/shared/Form/styles.module.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import "utils/utils.scss";

.DivWithLabel {
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -65,3 +67,23 @@
monospace;
}
}

.ImageUploader {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 10px;
div {
display: flex;
align-items: center;
gap: 20px;
}
button {
@include StyledButton;
height: 43px;
white-space: nowrap;
}
input {
@include StyledInput;
}
}
80 changes: 0 additions & 80 deletions client/components/shared/ImageUploader/ImageUploader.tsx

This file was deleted.

1 change: 0 additions & 1 deletion client/components/shared/ImageUploader/index.ts

This file was deleted.

21 changes: 0 additions & 21 deletions client/components/shared/ImageUploader/styles.module.scss

This file was deleted.

2 changes: 1 addition & 1 deletion server/build/database/models/Posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const initPosts = () => {
allowNull: false, //ν•„μˆ˜
},
thumbNailUrl: {
type: sequelize_1.DataTypes.STRING(100),
type: sequelize_1.DataTypes.TEXT,
allowNull: true, //ν•„μˆ˜
},
views: {
Expand Down
2 changes: 1 addition & 1 deletion server/src/database/models/Posts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const initPosts = () => {
allowNull: false, //ν•„μˆ˜
},
thumbNailUrl: {
type: DataTypes.STRING(100),
type: DataTypes.TEXT,
allowNull: true, //ν•„μˆ˜
},
views: {
Expand Down

1 comment on commit 6c42812

@vercel
Copy link

@vercel vercel bot commented on 6c42812 Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.