Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] Feature/#435 이미지 압축 기능 구현 #436

Merged
merged 5 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions frontend/src/hooks/useCompressImage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import imageCompression from 'browser-image-compression';

const useCompressImage = () => {
const compressImage = async (file: File) => {
const resizingBlob = await imageCompression(file, {
maxSizeMB: 1,
maxWidthOrHeight: 500,
Copy link
Collaborator

Choose a reason for hiding this comment

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

패트릭 이미지 가로 넓이가 704px 일 때도 있어용~ 모바일 최대 사이즈 (744px) 경우입니다. 따라서 500으로 설정하시면 이미지가 깨져보일 수도 있을 것 같아요.

이미지는 전체 코멘트에 첨부하겠습니다. 이미지가 너무 커서 코드 리뷰할 때 방해될 것 같네요.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

와우 놓칠 수도 있는 부분이었는데 반응형을 담당해주신 세인이라 캐치할 수 있었던 것 같습니다!! 👍

최대 사이즈 변경하도록 하겠습니다! 감사합니다!

useWebWorker: true,
});
const resizingFile = new File([resizingBlob], file.name, {
type: file.type,
});
return resizingFile;
};

const compressImageList = async (files: FileList) => {
const compressedImageList: File[] = [];

for (const file of files) {
const compressedImage = await compressImage(file);
compressedImageList.push(compressedImage);
Comment on lines +20 to +21
Copy link
Collaborator

Choose a reason for hiding this comment

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

재사용 베리 굿~~ 👍👍

}

return compressedImageList;
};

return { compressImage, compressImageList };
};

export default useCompressImage;
29 changes: 15 additions & 14 deletions frontend/src/pages/NewPin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Modal from '../components/Modal';
import { styled } from 'styled-components';
import ModalMyTopicList from '../components/ModalMyTopicList';
import { getMapApi } from '../apis/getMapApi';
import useCompressImage from '../hooks/useCompressImage';

type NewPinFormValueType = Pick<
NewPinFormProps,
Expand All @@ -49,6 +50,7 @@ const NewPin = () => {
const { showToast } = useToast();
const { width } = useSetLayoutWidth(SIDEBAR);
const { openModal, closeModal } = useContext(ModalContext);
const { compressImageList } = useCompressImage();

const [formImages, setFormImages] = useState<File[]>([]);

Expand Down Expand Up @@ -177,7 +179,9 @@ const NewPin = () => {
});
};

const onPinImageChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const onPinImageChange = async (
event: React.ChangeEvent<HTMLInputElement>,
) => {
const imageLists = event.target.files;
let imageUrlLists = [...showedImages];

Expand All @@ -189,8 +193,10 @@ const NewPin = () => {
return;
}

const compressedImageList = await compressImageList(imageLists);

for (let i = 0; i < imageLists.length; i++) {
const currentImageUrl = URL.createObjectURL(imageLists[i]);
const currentImageUrl = URL.createObjectURL(compressedImageList[i]);
imageUrlLists.push(currentImageUrl);
}

Expand All @@ -203,7 +209,7 @@ const NewPin = () => {
return;
}

setFormImages([...formImages, ...imageLists]);
setFormImages([...formImages, ...compressedImageList]);
setShowedImages(imageUrlLists);
};

Expand Down Expand Up @@ -239,16 +245,12 @@ const NewPin = () => {

<Space size={5} />

<Flex>
<Text color="black" $fontSize="default" $fontWeight="normal">
지도 선택
</Text>
<Space size={0} />
<Text color="primary" $fontSize="extraSmall" $fontWeight="normal">
*
</Text>
</Flex>
<Space size={0} />
<Text color="black" $fontSize="default" $fontWeight="normal">
지도 선택
</Text>

<Space size={2} />

<Button
type="button"
variant="primary"
Expand Down Expand Up @@ -410,7 +412,6 @@ const ModalContentsWrapper = styled.div`

const ImageInputLabel = styled.label`
height: 40px;
margin-left: 10px;
padding: 10px 10px;

color: ${({ theme }) => theme.color.black};
Expand Down
16 changes: 13 additions & 3 deletions frontend/src/pages/NewTopic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { TagContext } from '../context/TagContext';
import usePost from '../apiHooks/usePost';
import AuthorityRadioContainer from '../components/AuthorityRadioContainer';
import styled from 'styled-components';
import useCompressImage from '../hooks/useCompressImage';

type NewTopicFormValuesType = Omit<NewTopicFormProps, 'topics'>;

Expand All @@ -34,6 +35,7 @@ const NewTopic = () => {
description: '',
image: '',
});
const { compressImage } = useCompressImage();

const [isPrivate, setIsPrivate] = useState(false); // 혼자 볼 지도 : 같이 볼 지도
const [isAll, setIsAll] = useState(true); // 모두 : 지정 인원
Expand Down Expand Up @@ -116,7 +118,7 @@ const NewTopic = () => {
});
};

const onTopicImageFileChange = (
const onTopicImageFileChange = async (
event: React.ChangeEvent<HTMLInputElement>,
) => {
const file = event.target.files && event.target.files[0];
Expand All @@ -128,7 +130,9 @@ const NewTopic = () => {
return;
}

setFormImage(file);
const compressedFile = await compressImage(file);

setFormImage(compressedFile);
setShowImage(URL.createObjectURL(file));
};

Expand All @@ -143,7 +147,14 @@ const NewTopic = () => {
지도 생성
</Text>

<Space size={5} />

<Text color="black" $fontSize="default" $fontWeight="normal">
지도 선택
</Text>

<Space size={2} />

<Flex>
{showImage && <ShowImage src={showImage} alt={`사진 이미지`} />}
<ImageInputLabel htmlFor="file">파일업로드</ImageInputLabel>
Expand Down Expand Up @@ -241,7 +252,6 @@ const NewTopic = () => {

const ImageInputLabel = styled.label`
height: 40px;
margin-left: 10px;
Copy link
Collaborator

Choose a reason for hiding this comment

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

요 속성은 어떤 이유로 삭제되었을까용??

Copy link
Collaborator Author

@GC-Park GC-Park Sep 20, 2023

Choose a reason for hiding this comment

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

사진이 없으면 파일 추가 버튼이 다른 텍스트들과 왼쪽으로 정렬되지 않아 지웠었습니다!

그런데 사진이 있는 경우 버튼과 간격이 필요하니 그 부분은 space로 대체할 수 있을 것 같습니다!

수정하도록 하겠습니다~!!

padding: 10px 10px;
color: ${({ theme }) => theme.color.black};
background-color: ${({ theme }) => theme.color.lightGray};
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/pages/PinDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ModalContext } from '../context/ModalContext';
import AddToMyTopicList from '../components/ModalMyTopicList/addToMyTopicList';
import { postApi } from '../apis/postApi';
import PinImageContainer from '../components/PinImageContainer';
import useCompressImage from '../hooks/useCompressImage';

interface PinDetailProps {
width: '372px' | '100vw';
Expand Down Expand Up @@ -47,6 +48,7 @@ const PinDetail = ({
description: '',
});
const { openModal } = useContext(ModalContext);
const { compressImage } = useCompressImage();

const openModalWithToken = () => {
if (userToken) {
Expand Down Expand Up @@ -101,7 +103,9 @@ const PinDetail = ({
return;
}

formData.append('image', file);
const compressedFile = await compressImage(file);

formData.append('image', compressedFile);

const data = JSON.stringify(pinId);
const jsonBlob = new Blob([data], { type: 'application/json' });
Expand Down