Skip to content

Commit

Permalink
feature-081: 알림창에 영상 변환 상태 연결
Browse files Browse the repository at this point in the history
  • Loading branch information
gs0428 committed Feb 19, 2024
1 parent 4f1edc6 commit 1630ad3
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 76 deletions.
13 changes: 5 additions & 8 deletions src/apis/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
FindEmailRequest,
FindPasswordResponse,
FindPasswordRequest,
CreateVideoAlarmRequest
CreateVideoAlarmRequest,
} from '@/models/user';
import {
AlarmResponse,
Expand Down Expand Up @@ -93,11 +93,8 @@ export const createVideoAlarmAPI = (
PREFIX + `/videoAlarm/${videoId}/${status}`,
data,
);
}
};

export const findPasswordAPI = (data : FindPasswordRequest) => {
return axios.post<FindPasswordResponse>(
PREFIX + '/findPassword',
data
);
}
export const findPasswordAPI = (data: FindPasswordRequest) => {
return axios.post<FindPasswordResponse>(PREFIX + '/findPassword', data);
};
36 changes: 4 additions & 32 deletions src/components/Home/SearchYoutube.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import React, { useState, FormEvent } from 'react';
import { useNavigate } from 'react-router-dom';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';

import { createVideoAPI } from '@/apis/videos';
import { useRecoilState, useSetRecoilState } from 'recoil';

import VideoIcon from '@/assets/icons/video.svg?react';
import WarningIcon from '@/assets/icons/warning.svg?react';
Expand All @@ -17,30 +14,26 @@ import {

import { recommendationModalState } from '@/stores/modal';
import {
modelingDataState,
modelingProgressState,
modelingStatusState,
videoLinkState,
} from '@/stores/model-controller';
import { userTokenState } from '@/stores/user';

import { validateYoutubeLink } from '@/utils/validation';

import ProgressBar from './ProgressBar';
import useCreateVideo from '@/hooks/useCreateVideo';

type Props = {
searchRef: React.RefObject<HTMLInputElement>;
};

const SearchYoutube = ({ searchRef }: Props) => {
const navigate = useNavigate();

const userToken = useRecoilValue(userTokenState);
const setIsOpenModal = useSetRecoilState(recommendationModalState);
const setVideoLink = useSetRecoilState(videoLinkState);
const setProgress = useSetRecoilState(modelingProgressState);
const [status, setStatus] = useRecoilState(modelingStatusState);
const [modelingData, setModelingData] = useRecoilState(modelingDataState);
const { createVideo } = useCreateVideo();

const [inputLink, setInputLink] = useState('');

Expand Down Expand Up @@ -98,27 +91,6 @@ const SearchYoutube = ({ searchRef }: Props) => {
setProgress(0);
};

const handleClickCreateVideoButton = async () => {
if (!modelingData) return;

if (userToken) {
try {
const { video_id } = (await createVideoAPI(modelingData)).data.result;

navigate(`/summary/${video_id}`);
setModelingData(null);
} catch (e) {
console.error(e);
}
} else {
navigate('/summary/guest');
}

setVideoLink(null);
setStatus('NONE');
setProgress(0);
};

return (
<>
<SearchContainer className="dark-section">
Expand Down Expand Up @@ -172,7 +144,7 @@ const SearchYoutube = ({ searchRef }: Props) => {
color: theme.color.gray500,
backgroundColor: theme.color.green400,
}}
onClick={handleClickCreateVideoButton}
onClick={createVideo}
>
영상 읽기
</SearchButton>
Expand Down
10 changes: 10 additions & 0 deletions src/components/common/ModelController/ModelController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ const ModelController = () => {
setVideoLink(null);
};

const handleUpdateAlarm = async (title: string) => {
await createVideoAlarmAPI(0, 'success', {
title: `[${title}]`,
content:
'영상이 모두 변환되었어요!\n이제 정리 된 영상을 확인하러 가볼까요?',
is_confirm: false,
});
};

useEffect(() => {
if (!videoLink) return;

Expand Down Expand Up @@ -89,6 +98,7 @@ const ModelController = () => {

setModelingData(finalData);
setModelingProgress(100);
handleUpdateAlarm(finalData.title);
setModelingStatus('COMPLETE');
} catch (e) {
console.error(e);
Expand Down
43 changes: 42 additions & 1 deletion src/components/layout/header/alarm/AlarmItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,34 @@ import ErrorImage from '@/assets/Error.png';
import { Container } from '@/styles/layout/header/alarm/AlarmItem.style';

import { diffTime } from '@/utils/date';
import { useRecoilValue } from 'recoil';
import {
modelingProgressState,
modelingStatusState,
} from '@/stores/model-controller';
import theme from '@/styles/theme';
import useCreateVideo from '@/hooks/useCreateVideo';
import { confirmSelectAlarmAPI } from '@/apis/user';

type Props = {
alarm: IAlarm;
selectIdList: number[];
onUpdateSelectIdList: (list: number[]) => void;
onClose: () => void;
onRefresh: () => void;
};

const AlarmItem = ({
alarm,
selectIdList,
onUpdateSelectIdList,
onClose,
onRefresh,
}: Props) => {
const navigate = useNavigate();
const status = useRecoilValue(modelingStatusState);
const progress = useRecoilValue(modelingProgressState);
const { createVideo } = useCreateVideo();
const isSelected = selectIdList.indexOf(alarm.alarm_id) > -1;

const type = () => {
Expand Down Expand Up @@ -58,11 +71,22 @@ const AlarmItem = ({
return `${second}초`;
};

const handleClick = () => {
const handleClick = async () => {
if (alarm.type === 'notice') {
navigate('/guide');
onClose();
}
if (alarm.type === 'video' && !alarm.is_confirm) {
try {
await confirmSelectAlarmAPI({ alarms: [alarm.alarm_id] });

onRefresh();
createVideo();
onClose();
} catch (e) {
console.error(e);
}
}
};

const handleClickRemoveButton: React.MouseEventHandler<HTMLButtonElement> = (
Expand Down Expand Up @@ -110,6 +134,23 @@ const AlarmItem = ({
<span>{alarm.content}</span>
</div>
</div>
{status !== 'NONE' && alarm.alarm_id === 999 && (
<div className="progress-wrap">
<div className="progress-bar">
<div
style={{
width: `${progress}%`,
backgroundColor:
status === 'ERROR' ? theme.color.red : theme.color.green300,
}}
/>
</div>

<span className="progress-text">
{status === 'ERROR' ? '변환 중 오류' : `${progress}%`}
</span>
</div>
)}
</Container>
);
};
Expand Down
1 change: 1 addition & 0 deletions src/components/layout/header/alarm/AlarmList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ const AlarmList = ({ alarmList, onRefresh, onClose }: Props) => {
selectIdList={selectIdList}
onUpdateSelectIdList={setSelectIdList}
onClose={onClose}
onRefresh={onRefresh}
/>
))}
</div>
Expand Down
20 changes: 19 additions & 1 deletion src/components/layout/header/alarm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,27 @@ const Alarm = ({ isDark }: Props) => {
}, []);

useEffect(() => {
if (status === 'ERROR') {
if (status === 'ERROR' || status === 'COMPLETE') {
console.log(status, 'dd');
callAPI();
}

if (status === 'CONTINUE') {
setAlarmList([
{
state: 'success',
type: 'video',
alarm_id: 999,
title: '열심히 영상을 변환하는 중이에요!',
content: '잠시후 멋진 글을 만날 수 있어요:)',
is_confirm: 0,
created_at: new Date().toString(),
updated_at: new Date().toString(),
},
...alarmList,
]);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [status]);

return (
Expand Down
41 changes: 7 additions & 34 deletions src/components/layout/sideBar/ConvertVideo.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';

import { createVideoAPI } from '@/apis/videos';
import { useLocation } from 'react-router-dom';
import { useRecoilValue, useSetRecoilState } from 'recoil';

import VideoSvg from '@/assets/icons/video.svg?react';
import DownSvg from '@/assets/icons/down.svg?react';
Expand All @@ -13,55 +11,30 @@ import { CommonTitle } from '@/styles/layout/sideBar/UserMode.style';

import { recommendationModalState } from '@/stores/modal';
import {
modelingDataState,
modelingProgressState,
modelingStatusState,
videoLinkState,
} from '@/stores/model-controller';
import { userTokenState } from '@/stores/user';

import theme from '@/styles/theme';

import { validateYoutubeLink } from '@/utils/validation';
import useCreateVideo from '@/hooks/useCreateVideo';

const ConvertVideo = () => {
const { pathname } = useLocation();
const navigate = useNavigate();

const userToken = useRecoilValue(userTokenState);
const setIsOpenModal = useSetRecoilState(recommendationModalState);
const setVideoLink = useSetRecoilState(videoLinkState);
const [status, setStatus] = useRecoilState(modelingStatusState);
const [progress, setProgress] = useRecoilState(modelingProgressState);
const [modelingData, setModelingData] = useRecoilState(modelingDataState);
const status = useRecoilValue(modelingStatusState);
const progress = useRecoilValue(modelingProgressState);
const { createVideo } = useCreateVideo();

const [isOpen, setIsOpen] = useState(false);
const [isFocus, setIsFocus] = useState(false);
const [url, setURL] = useState('');

const isValidate = validateYoutubeLink(url);

const handleClickCreateVideoButton = async () => {
if (!modelingData) return;

if (userToken) {
try {
const { video_id } = (await createVideoAPI(modelingData)).data.result;

navigate(`/summary/${video_id}`);
setModelingData(null);
} catch (e) {
console.error(e);
}
} else {
navigate('/summary/guest');
}

setVideoLink(null);
setStatus('NONE');
setProgress(0);
};

const handleClickStartConvertButton: React.MouseEventHandler<
HTMLButtonElement
> = (e) => {
Expand Down Expand Up @@ -112,7 +85,7 @@ const ConvertVideo = () => {
color: theme.color.gray500,
backgroundColor: theme.color.green400,
}}
onClick={handleClickCreateVideoButton}
onClick={createVideo}
>
start
</ConvertVideoStyle.Button>
Expand Down
44 changes: 44 additions & 0 deletions src/hooks/useCreateVideo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { createVideoAPI } from '@/apis/videos';
import {
modelingDataState,
modelingProgressState,
modelingStatusState,
videoLinkState,
} from '@/stores/model-controller';
import { userTokenState } from '@/stores/user';
import { useNavigate } from 'react-router-dom';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';

const useCreateVideo = () => {
const [modelingData, setModelingData] = useRecoilState(modelingDataState);
const userToken = useRecoilValue(userTokenState);
const setVideoLink = useSetRecoilState(videoLinkState);
const setStatus = useSetRecoilState(modelingStatusState);
const setProgress = useSetRecoilState(modelingProgressState);
const navigate = useNavigate();

const createVideo = async () => {
if (!modelingData) return;

if (userToken) {
try {
const { video_id } = (await createVideoAPI(modelingData)).data.result;

navigate(`/summary/${video_id}`);
setModelingData(null);
} catch (e) {
console.error(e);
}
} else {
navigate('/summary/guest');
}

setVideoLink(null);
setStatus('NONE');
setProgress(0);
};

return { createVideo };
};

export default useCreateVideo;
Loading

0 comments on commit 1630ad3

Please sign in to comment.