Skip to content

Commit

Permalink
[온보딩] step02 썸네일 등록 시 아이폰 이미지 확장자(heic) 업로드 안되는 현상 수정 (#497)
Browse files Browse the repository at this point in the history
* chore: heic 변환 라이브러리 설치

* feat: heic 확장자 input으로 받도록 추가

* refactor: 함수 분리 & 고용량 이미지 이슈 예외처리

이미지 업로드가 되는 것을 진행해놓은 상태에서
다시 고용량 이미지를 추가하면 이미지 업로드가 되는 현상이 있어
이를 수정하였습니다.

* feat: heic 확장자 업로드 가능하도록 수정

* fix: step02 파일 인풋 대소문자 구분x로 인해 확장자 하나 삭제

* chore: 콘솔로그 제거
  • Loading branch information
ExceptAnyone authored Mar 14, 2024
1 parent a4ea7dd commit c8ec4f8
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 69 deletions.
4 changes: 1 addition & 3 deletions src/components/OnBoardingSteps/Step02/Step02.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ const ThumbnailInput = React.memo((props: ThumbnailInputProps) => {
/** @todo 파일네임 파싱하는 함수 유틸로 처리 */
setIsLoading(true);
const presignedUrl = data.presignedUrl.split('?')[0];
console.log('data.presignedUrl', data.presignedUrl);
console.log('parsingpresignedUrl', presignedUrl);
updateOnboardingInfo({ imageUrl: presignedUrl });
if (previewImageInfo.file) {
await binarizeAndPutImage({ presignedUrl, file: previewImageInfo.file });
Expand All @@ -57,7 +55,7 @@ const ThumbnailInput = React.memo((props: ThumbnailInputProps) => {
<S.IcEmptyThumbnailWrapper>
<input
type='file'
accept='image/jpeg, image/png, image/gif, image/heic '
accept='image/jpeg, image/png, image/gif, image/heic, image/webp'
style={{ display: 'none' }}
id='imgInput'
onChange={handleImageUpload}
Expand Down
8 changes: 0 additions & 8 deletions src/context/Onboarding/OnboardingContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
SetStateAction,
createContext,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
Expand Down Expand Up @@ -41,13 +40,6 @@ export const OnboardingProvider = ({ children }: PropsWithChildren) => {
setOnboardingInfo((prev) => ({ ...prev, ...newInfo }));
};

/**@todo 전체 값 확인용 useEffect */
useEffect(() => {
console.log('전체 값 확인:', onboardingInfo);
console.log('context 속 selectedTime', selectedTime);
console.log('context 속 typeof selectedTime', typeof selectedTime);
}, [onboardingInfo, selectedTime]);

const OnboardingInfoContextValue = useMemo(
() => ({
onboardingInfo,
Expand Down
145 changes: 88 additions & 57 deletions src/hooks/common/usePreviewImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,103 @@ import { toast } from 'react-toastify';
import { usePreviewImageContext } from '../../context/Onboarding/PreviewImageContext';
import { IMAGE_HEIGHT, MESSAGE } from '../../core/toast-messages';
import Resizer from 'react-image-file-resizer';
import heic2any from 'heic2any';

const usePreviewImage = () => {
const { previewImageInfo, updatePreviewImageInfo } = usePreviewImageContext();

const handleImageUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
const { files } = event.target;
const uploadFalse = () => {
updatePreviewImageInfo({
isImageUploaded: false,
file: null,
previewImage: null,
imageName: '',
});
};

const uploadFalse = () => {
updatePreviewImageInfo({
isImageUploaded: false,
file: null,
previewImage: null,
imageName: '',
});
};
const resizedFile = (file: File, previewImage: string) => {
new Promise((resolve) => {
Resizer.imageFileResizer(
file,
480,
480,
'WEBP',
75,
0,
(uri) => {
updatePreviewImageInfo({
isImageUploaded: true,
imageName: (uri as File).name,
file: uri as File,
previewImage: previewImage,
});
resolve(uri);
},
'file',
);
});
};

const resizedFile = (file: File, previewImage: string) => {
new Promise((resolve) => {
Resizer.imageFileResizer(
file,
480,
480,
'WEBP',
75,
0,
(uri) => {
updatePreviewImageInfo({
isImageUploaded: true,
imageName: (uri as File).name,
file: uri as File,
previewImage: previewImage,
});
resolve(uri);
console.log('됐다?');
},
'file',
);
});
const isFailUploadImageToast = (selectedFile: Blob | MediaSource) => {
const img = new Image();

img.onload = function () {
if (img.height <= IMAGE_HEIGHT.MIN) {
// 이미지 너비가 어느 수준 이하일 때 업로드 x
toast(MESSAGE.HEIGHT_SMALL);
uploadFalse();
} else if (img.height > IMAGE_HEIGHT.MAX) {
toast(MESSAGE.HEIGHT_BIG);
uploadFalse();
}
};

if (files && files.length > 0) {
const selectedFiles = files as FileList;
/**@see 추후 유니크한 이미지 네임 필요할 수 있으니 일단 주석처리 */
// const imageName = files[0].name.trim();

/**@todo 파싱 유틸 함수 공용으로 따로 작성 */
// const uploadTime = new Date().toISOString();

// const uniqueName = `${uploadTime}${imageName}`;
// const finalImageName = uniqueName
// .replace(/\//g, '') // 폴더링 방지를 위해 '/' 제거
// .replace(/\s/g, ''); // 공백 제거
resizedFile(selectedFiles[0], URL.createObjectURL(selectedFiles[0]));

const img = new Image();
img.onload = function () {
if (img.height <= IMAGE_HEIGHT.MIN) {
// 이미지 너비가 어느 수준 이하일 때 업로드 x
toast(MESSAGE.HEIGHT_SMALL);
uploadFalse();
} else if (img.height > IMAGE_HEIGHT.MAX) {
toast(MESSAGE.HEIGHT_BIG);
uploadFalse();
img.src = URL.createObjectURL(selectedFile);
};

const handleImageUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
const { files } = event.target;

try {
if (files && files.length > 0) {
const selectedFiles = files as FileList;

let convertedFile = selectedFiles[0];

if (selectedFiles[0].type === 'image/heic' || selectedFiles[0].type === 'image/HEIC') {
let blob = selectedFiles[0];
console.log('blob', blob);
const resultBlob = await heic2any({ blob, toType: 'image/webp' });
convertedFile = new File(
[resultBlob as Blob],
selectedFiles[0].name.split('.')[0] + '.webp',
{ type: 'image/webp', lastModified: new Date().getTime() },
);
updatePreviewImageInfo({
isImageUploaded: true,
imageName: convertedFile.name,
file: convertedFile,
previewImage: URL.createObjectURL(selectedFiles[0]),
});
}
};
img.src = URL.createObjectURL(selectedFiles[0]);

/**@see 추후 유니크한 이미지 네임 필요할 수 있으니 일단 주석처리 */
// const imageName = files[0].name.trim();

/**@todo 파싱 유틸 함수 공용으로 따로 작성 */
// const uploadTime = new Date().toISOString();

// const uniqueName = `${uploadTime}${imageName}`;
// const finalImageName = uniqueName
// .replace(/\//g, '') // 폴더링 방지를 위해 '/' 제거
// .replace(/\s/g, ''); // 공백 제거

isFailUploadImageToast(selectedFiles[0]);

resizedFile(selectedFiles[0], URL.createObjectURL(selectedFiles[0]));
}
} catch (err) {
console.log('error:', err);
}
};

Expand Down
1 change: 0 additions & 1 deletion src/hooks/onboarding/useFormatDate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const useFormatDate = () => {
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
// const minutes = date.getMinutes();

if (includeTime) {
return `${year}.${month}.${day}(${getDayOfWeek(date)}) ${hours}시`;
Expand Down

0 comments on commit c8ec4f8

Please sign in to comment.