Skip to content

Commit

Permalink
Merge pull request #252 from Team-Lecue/refactor/CreateNote
Browse files Browse the repository at this point in the history
dev로 들어가걸아ㅏ ~~!!!!!!!!
  • Loading branch information
Arooming authored Feb 23, 2024
2 parents c7d62bc + 42dba39 commit d7612ef
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 21 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"axios": "^1.6.5",
"eslint-plugin-react": "^7.33.2",
"grapheme-splitter": "^1.0.4",
"heic2any": "^0.0.4",
"lottie-react": "^2.4.0",
"postcss": "^8.4.33",
"postcss-styled-syntax": "^0.6.3",
Expand Down
5 changes: 4 additions & 1 deletion src/LecueNote/components/SelectColor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ function SelectColor({
handleColorFn,
handleIconFn,
selectedFile,
handleIsLoading,
}: SelectColorProps) {
const { textColor, background, category } = lecueNoteState;
const { textColor, background, category, contents } = lecueNoteState;

return (
<S.Wrapper>
Expand All @@ -43,11 +44,13 @@ function SelectColor({
isIconClicked={isIconClicked}
colorChart={category === '텍스트색' ? TEXT_COLOR_CHART : BG_COLOR_CHART}
state={category === '텍스트색' ? textColor : background}
contents={contents}
handleTransformImgFile={handleTransformImgFile}
presignedUrlDispatch={presignedUrlDispatch}
selectedFile={selectedFile}
handleFn={handleColorFn}
handleIconFn={handleIconFn}
handleIsLoading={handleIsLoading}
/>
</S.Wrapper>
);
Expand Down
54 changes: 37 additions & 17 deletions src/LecueNote/components/ShowColorChart/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,63 @@ import { IcCameraSmall } from '../../../assets';
import { BG_COLOR_CHART } from '../../constants/colorChart';
import useGetPresignedUrl from '../../hooks/useGetPresignedUrl';
import { ShowColorChartProps } from '../../type/lecueNoteType';
import handleClickFiletoBinary from '../../util/handleClickFiletoBinary';
import handleClickFiletoString from '../../util/handleClickFiletoString';
import handleClickHeicToJpg from '../../util/handleClickHeicToJpg';
import * as S from './ShowColorChart.style';

function ShowColorChart({
isIconClicked,
colorChart,
state,
contents,
handleTransformImgFile,
presignedUrlDispatch,
selectedFile,
handleFn,
handleIconFn,
handleIsLoading,
}: ShowColorChartProps) {
const imgRef = useRef<HTMLInputElement | null>(null);
useGetPresignedUrl({ presignedUrlDispatch });

const handleChangeContents = () => {
sessionStorage.setItem('noteContents', contents ? contents : '');
};

const handleReaderOnloadend = (reader: FileReader, file: File) => {
handleTransformImgFile(reader);
selectedFile(file);
};

const handleImageUpload = () => {
const fileInput = imgRef.current;

if (fileInput && fileInput.files && fileInput.files.length > 0) {
const file = fileInput.files[0];

// reader1: 파일을 base64로 읽어서 업로드
const reader1 = new FileReader();
reader1.readAsDataURL(file);
reader1.onloadend = () => {
if (reader1.result !== null) {
handleTransformImgFile(reader1.result as string);
}
};
if (file.name.split('.')[1].toUpperCase() === 'HEIC') {
handleClickHeicToJpg({
file: file,
handleTransformImgFile,
handleReaderOnloadend,
handleIsLoading,
});
} else {
const reader1 = new FileReader();
handleClickFiletoString({
file: file,
reader: reader1,
handleTransformImgFile,
});

// reader2: 파일을 ArrayBuffer로 읽어서 PUT 요청 수행
const reader2 = new FileReader();
reader2.readAsArrayBuffer(file);
// reader1의 비동기 작업이 완료된 후 수행(onloadend() 활용)
reader2.onloadend = () => {
handleTransformImgFile(reader2);
selectedFile(file);
};
const reader2 = new FileReader();
handleClickFiletoBinary({
file: file,
reader: reader2,
handleReaderOnloadend,
});
}
}
};

Expand All @@ -51,14 +70,15 @@ function ShowColorChart({
<>
<S.Input
type="file"
accept="image/*"
accept="image/*, image/heic"
onChange={handleImageUpload}
ref={imgRef}
/>

<S.IconWrapper
onClick={() => {
handleIconFn();
handleChangeContents();
imgRef.current?.click();
}}
$isIconClicked={isIconClicked}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import styled from '@emotion/styled';

export const LoadingWrapper = styled.div`
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 0.6rem;
background-color: ${({ theme }) => theme.colors.background};
`;

export const LottieWrapper = styled.div`
width: 10rem;
height: 10rem;
`;
24 changes: 24 additions & 0 deletions src/LecueNote/components/WriteNote/NoteLoading/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Lottie from 'lottie-react';
import { useEffect } from 'react';

import animationData from '../../../../../src/assets/lottie/spiner 120.json';
import * as S from './NoteLoading.style';

interface NoteLoadingProps {
handleResetPrevImg: () => void;
}
const NoteLoading = ({ handleResetPrevImg }: NoteLoadingProps) => {
useEffect(() => {
handleResetPrevImg();
}, []);

return (
<S.LoadingWrapper>
<S.LottieWrapper>
<Lottie animationData={animationData} />
</S.LottieWrapper>
</S.LoadingWrapper>
);
};

export default NoteLoading;
1 change: 1 addition & 0 deletions src/LecueNote/components/WriteNote/WriteNote.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const LecueNote = styled.article<{
}>`
display: flex;
flex-direction: column;
position: relative;
width: 100%;
height: calc(100dvh - 33.2rem);
Expand Down
5 changes: 5 additions & 0 deletions src/LecueNote/components/WriteNote/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ import GraphemeSplitter from 'grapheme-splitter';
import { useEffect, useState } from 'react';

import { WriteNoteProps } from '../../type/lecueNoteType';
import NoteLoading from './NoteLoading';
import * as S from './WriteNote.style';

function WriteNote({
isLoading,
lecueNoteState,
imgFile,
isIconClicked,
contents,
handleChangeFn,
handleResetPrevImg,
}: WriteNoteProps) {
const nickname = localStorage.getItem('nickname');
const { textColor, background } = lecueNoteState;
Expand All @@ -30,6 +33,8 @@ function WriteNote({
$isIconClicked={isIconClicked}
$imgFile={imgFile}
>
{isLoading && <NoteLoading handleResetPrevImg={handleResetPrevImg} />}

<S.Nickname $textColor={textColor}>{nickname}</S.Nickname>
<S.Contents
$textColor={textColor}
Expand Down
22 changes: 20 additions & 2 deletions src/LecueNote/page/LeceuNotePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ function LecueNotePage() {
const location = useLocation();
const putMutation = usePutPresignedUrl();
const postMutation = usePostLecueNote();
const noteContents = sessionStorage.getItem('noteContents');
const { bookId } = location.state || {};

const [modalOn, setModalOn] = useState(false);
const [escapeModal, setEscapeModal] = useState(false);
const [isLoading, setIsLoading] = useState(false);

const [lecueNoteState, dispatch] = useReducer(reducer, {
presignedUrl: '',
filename: BG_COLOR_CHART[0],
contents: '',
contents: noteContents !== null ? noteContents : '',
category: CATEGORY[0],
textColor: TEXT_COLOR_CHART[0],
background: BG_COLOR_CHART[0],
Expand All @@ -41,6 +43,14 @@ function LecueNotePage() {
imgToBinary: new FileReader(),
});

const handleIsLoading = (booleanStatus: boolean) => {
setIsLoading(booleanStatus);
};

const handleResetPrevImg = () => {
dispatch({ type: 'RESET_PREV_IMG' });
};

const handleChangeContents = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
dispatch({ type: 'SET_CONTENTS', contents: e.target.value });
if (e.target.value.length > MAX_LENGTH) {
Expand Down Expand Up @@ -89,6 +99,8 @@ function LecueNotePage() {
isIconClicked: lecueNoteState.isIconClicked,
bookId: bookId,
});

sessionStorage.setItem('noteContents', '');
};

return putMutation.isLoading || postMutation.isLoading ? (
Expand All @@ -105,7 +117,10 @@ function LecueNotePage() {

{escapeModal && (
<CommonModal
handleFn={() => navigate(-1)}
handleFn={() => {
navigate(-1);
sessionStorage.setItem('noteContents', '');
}}
category="note_escape"
setModalOn={setEscapeModal}
/>
Expand All @@ -117,11 +132,13 @@ function LecueNotePage() {

<S.CreateNote>
<WriteNote
isLoading={isLoading}
imgFile={lecueNoteState.imgToStr}
isIconClicked={lecueNoteState.isIconClicked}
lecueNoteState={lecueNoteState}
contents={lecueNoteState.contents}
handleChangeFn={handleChangeContents}
handleResetPrevImg={handleResetPrevImg}
/>
<SelectColor
isIconClicked={lecueNoteState.isIconClicked}
Expand All @@ -139,6 +156,7 @@ function LecueNotePage() {
}
handleColorFn={handleClickedColorBtn}
handleIconFn={() => dispatch({ type: 'CLICKED_IMG_ICON' })}
handleIsLoading={handleIsLoading}
/>
</S.CreateNote>

Expand Down
3 changes: 3 additions & 0 deletions src/LecueNote/reducer/lecueNoteReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ export const reducer = (state: State, action: Action): State => {
case 'IMG_TO_BINARY':
return { ...state, imgToBinary: action.imgFile };

case 'RESET_PREV_IMG':
return { ...state, imgToStr: '' };

default:
throw new Error('Unhandled action');
}
Expand Down
6 changes: 6 additions & 0 deletions src/LecueNote/type/lecueNoteType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface SelectColorProps {
textColor: string;
background: string;
category?: string;
contents?: string;
};
selectedFile: (file: File) => void;
presignedUrlDispatch: React.Dispatch<{
Expand All @@ -17,12 +18,14 @@ export interface SelectColorProps {
handleColorFn: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
handleIconFn: () => void;
handleTransformImgFile: (file: string | FileReader) => void;
handleIsLoading: (status: boolean) => void;
}

export interface ShowColorChartProps {
isIconClicked: boolean;
colorChart: string[];
state: string;
contents?: string;
handleTransformImgFile: (file: string | FileReader) => void;
selectedFile: (file: File) => void;
handleFn: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
Expand All @@ -32,9 +35,11 @@ export interface ShowColorChartProps {
presignedUrl: string;
filename: string;
}>;
handleIsLoading: (status: boolean) => void;
}

export interface WriteNoteProps {
isLoading: boolean;
imgFile: string;
isIconClicked: boolean;
lecueNoteState: {
Expand All @@ -44,6 +49,7 @@ export interface WriteNoteProps {
};
contents: string;
handleChangeFn: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
handleResetPrevImg: () => void;
}

export interface FooterProps {
Expand Down
3 changes: 2 additions & 1 deletion src/LecueNote/type/reducerType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export type Action =
| { type: 'CLICKED_IMG_ICON' }
| { type: 'NOT_CLICKED_IMG_ICON' }
| { type: 'IMG_TO_STR'; imgFile: string }
| { type: 'IMG_TO_BINARY'; imgFile: FileReader };
| { type: 'IMG_TO_BINARY'; imgFile: FileReader }
| { type: 'RESET_PREV_IMG'; };
19 changes: 19 additions & 0 deletions src/LecueNote/util/handleClickFiletoBinary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
interface handleClickFiletoBinaryProps {
file: File;
reader: FileReader;
handleReaderOnloadend: (reader: FileReader, file: File) => void;
}

const handleClickFiletoBinary = ({
file,
reader,
handleReaderOnloadend,
}: handleClickFiletoBinaryProps) => {
reader.readAsArrayBuffer(file);
// reader1의 비동기 작업이 완료된 후 수행(onloadend() 활용)
reader.onloadend = () => {
handleReaderOnloadend(reader, file);
};
};

export default handleClickFiletoBinary;
20 changes: 20 additions & 0 deletions src/LecueNote/util/handleClickFiletoString.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
interface handleClickFiletoStringProps {
file: File;
reader: FileReader;
handleTransformImgFile: (file: string | FileReader) => void;
}

const handleClickFiletoString = ({
file,
reader,
handleTransformImgFile,
}: handleClickFiletoStringProps) => {
reader.readAsDataURL(file);
reader.onloadend = () => {
if (reader.result !== null) {
handleTransformImgFile(reader.result as string);
}
};
};

export default handleClickFiletoString;
Loading

0 comments on commit d7612ef

Please sign in to comment.