Skip to content

Commit

Permalink
feature-074: 모델링 연동 진행중
Browse files Browse the repository at this point in the history
  • Loading branch information
whistleJs committed Feb 19, 2024
1 parent 1f97077 commit 6a33fd0
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 40 deletions.
11 changes: 10 additions & 1 deletion src/apis/videos.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { APIBaseResponse, APIResponse } from '@/models/config/axios';
import { ModelingFinalData } from '@/models/modeling';
import {
IVideo,
UpdateVideoCategoryRequest,
Expand All @@ -13,7 +14,7 @@ import { IVideoProps } from 'types/videos';

const PREFIX = '/videos';

export const createVideoAPI = (data: IVideo) => {
export const createVideoAPI = (data: ModelingFinalData) => {
return axios.post<APIResponse<IVideo>>(PREFIX + `/new-video`, data);
};

Expand All @@ -24,6 +25,10 @@ export const getVideoAPI = (
return axios.get<APIResponse<IVideo>>(PREFIX + `/${videoId}/${versionId}`);
};

export const getDummyVideoAPI = (videoId: string | number) => {
return axios.get<APIResponse<IVideo>>(PREFIX + `/dummyVideos/${videoId}/get`);
};

export const deleteVideos = async (videos: number[] | undefined) => {
const response = await axiosInstance.delete('/videos/selectDelete', {
data: { videos },
Expand Down Expand Up @@ -76,6 +81,10 @@ export const getUnReadDummyVideosAPI = () => {
return axios.get<APIResponse<VideoResponse>>('/videos/dummyVideos/unRead');
};

export const getAllDummyVideosAPI = () => {
return axios.get<APIResponse<VideoResponse>>('/videos/dummyVideos');
};

export const getUnReadDummyVideos = async (): Promise<
APIResponse<Record<'videos', IVideoProps[]>>
> => {
Expand Down
1 change: 1 addition & 0 deletions src/components/Home/SearchYoutube.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const SearchYoutube = ({ searchRef }: Props) => {
setVideoLink(null);
setStatus('NONE');
setProgress(0);
setModelingData(null);
};

const handleClickCreateVideoButton = async () => {
Expand Down
12 changes: 8 additions & 4 deletions src/components/SummaryPage/SummaryDetailBox/SummaryDetailBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ const SummaryDetailBox = ({ onRefresh }: Props) => {
}
};

useEffect(() => {
return () => {
setSummaryVideoTime(0);
setPlaySubHeadingId(-1);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
if (player.current) return;

Expand All @@ -102,10 +110,6 @@ const SummaryDetailBox = ({ onRefresh }: Props) => {

window.onmessage = handleMessage;

return () => {
setSummaryVideoTime(0);
setPlaySubHeadingId(-1);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [summaryVideo]);

Expand Down
44 changes: 27 additions & 17 deletions src/components/common/ModelController/ModelController.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { useEffect, useRef } from 'react';
import { useRecoilState, useSetRecoilState } from 'recoil';

import {
modelingProcess1,
modelingProcess2,
modelingProcess3,
} from '@/apis/video';
import { useRecoilState, useSetRecoilState, useRecoilValue } from 'recoil';

import {
modelingDataState,
modelingProgressState,
modelingStatusState,
videoLinkState,
} from '@/stores/model-controller';
import {
modelingProcess1,
modelingProcess2,
modelingProcess3,
} from '@/apis/video';
import { userTokenState } from '@/stores/user';

import { createVideoAlarmAPI } from '@/apis/user';

const ModelController = () => {
const interval = useRef<NodeJS.Timeout>();
const userToken = useRecoilValue(userTokenState);
const [videoLink, setVideoLink] = useRecoilState(videoLinkState);
const setModelingStatus = useSetRecoilState(modelingStatusState);
const setModelingProgress = useSetRecoilState(modelingProgressState);
Expand All @@ -32,11 +34,13 @@ const ModelController = () => {

const handleError = async () => {
try {
await createVideoAlarmAPI(0, 'fail', {
title: '앗, 영상 변환 중 오류가 생겼어요',
content: '어떤 문제인지 확인해보세요!',
is_confirm: false,
});
if (userToken) {
await createVideoAlarmAPI(0, 'fail', {
title: '앗, 영상 변환 중 오류가 생겼어요',
content: '어떤 문제인지 확인해보세요!',
is_confirm: false,
});
}
} catch (e) {
console.error(e);
}
Expand All @@ -45,6 +49,8 @@ const ModelController = () => {
clearInterval(interval.current);
}

clearInterval(interval.current);

setModelingStatus('ERROR');
setVideoLink(null);
};
Expand All @@ -53,6 +59,8 @@ const ModelController = () => {
if (!videoLink) return;

const callProcess1API = async () => {
setModelingProgress(Math.ceil(Math.random() * 5));

try {
const { videoId } = (await modelingProcess1(videoLink)).data.result;

Expand Down Expand Up @@ -83,11 +91,14 @@ const ModelController = () => {
try {
const { finalData } = (await modelingProcess3({ videoId })).data.result;

if (interval.current) {
clearInterval(interval.current);
}
clearInterval(interval.current);

setModelingData(finalData);
setModelingData({
...finalData,
youtube_id: videoId,
created_at: new Date().toString(),
updated_at: new Date().toString(),
});
setModelingProgress(100);
setModelingStatus('COMPLETE');
} catch (e) {
Expand All @@ -98,7 +109,6 @@ const ModelController = () => {
};

setModelingStatus('CONTINUE');
setModelingProgress(Math.ceil(Math.random() * 5));
callProcess1API();
startInterval();
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down
17 changes: 13 additions & 4 deletions src/components/modals/RecommendationModal.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import { useSetRecoilState, useRecoilValue } from 'recoil';

import { getUnReadDummyVideosAPI } from '@/apis/videos';
import { getAllDummyVideosAPI, getUnReadDummyVideosAPI } from '@/apis/videos';

import CloseIcon from '@/assets/icons/close.svg?react';
import TransformationIcon from '@/assets/icons/transformation.svg?react';
Expand All @@ -12,10 +12,12 @@ import useOutsideClick from '@/hooks/useOutsideClick';
import { IVideo } from '@/models/video';

import { recommendationModalState } from '@/stores/modal';
import { userTokenState } from '@/stores/user';

import { RecommendationModalContainer } from '@/styles/modals/RecommendationModal.style';

const RecommendationModal = () => {
const userToken = useRecoilValue(userTokenState);
const setIsOpenModal = useSetRecoilState(recommendationModalState);
const [dummyVideo, setDummyVideo] = useState<IVideo>();

Expand All @@ -25,18 +27,25 @@ const RecommendationModal = () => {

useEffect(() => {
const callAPI = async () => {
let videos: IVideo[] = [];

try {
const { videos } = (await getUnReadDummyVideosAPI()).data.result;
const random = Math.round(Math.random() * (videos.length - 1));

if (userToken) {
videos = (await getUnReadDummyVideosAPI()).data.result.videos;
} else {
videos = (await getAllDummyVideosAPI()).data.result.videos;
}

setDummyVideo(videos[random]);
} catch (e) {
console.error(e);
}
};

callAPI();
}, [setDummyVideo]);
}, [userToken, setDummyVideo]);

return (
<RecommendationModalContainer>
Expand Down
33 changes: 30 additions & 3 deletions src/models/modeling.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { IVideo } from './video';

export type ModelingStatus =
| 'NONE'
| 'CONTINUE'
Expand All @@ -17,7 +15,36 @@ export interface ModelingProcessRequest {
videoId: string;
}

export interface ModelingSubHeading {
content: string;
end_time: number;
name: string;
start_time: number;
}

export interface ModelingSummary {
content: string;
}

export interface ModelingTag {
name: string;
}

export interface ModelingFinalData {
description: string;
link: string;
subheading: ModelingSubHeading[];
summary: ModelingSummary[];
tag: ModelingTag[];
title: string;
youtube_created_at: string;
youtube_id: string;

created_at: string;
updated_at: string;
}

export interface ModelingResponse {
finalData: IVideo;
finalData: ModelingFinalData;
message: string;
}
73 changes: 66 additions & 7 deletions src/pages/SummaryPage.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,104 @@
import { useCallback, useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useRecoilState } from 'recoil';
import { useNavigate, useParams, useLocation } from 'react-router-dom';
import { useRecoilState, useRecoilValue } from 'recoil';

import { getVideoAPI } from '@/apis/videos';
import { getDummyVideoAPI, getVideoAPI } from '@/apis/videos';

import { SummaryDetailBox } from '@/components/SummaryPage';
import { SummaryScriptBox } from '@/components/SummaryPage';

import { IVideo } from '@/models/video';

import { modelingDataState } from '@/stores/model-controller';
import { summaryVideoState } from '@/stores/summary';
import { userTokenState } from '@/stores/user';

import { Container } from '@/styles/SummaryPage';

const SummaryPage = () => {
const navigate = useNavigate();
const { videoId } = useParams();
const { search } = useLocation();

const userToken = useRecoilValue(userTokenState);
const [modelingData, setModelingData] = useRecoilState(modelingDataState);

Check failure on line 24 in src/pages/SummaryPage.tsx

View workflow job for this annotation

GitHub Actions / build (18.x)

'setModelingData' is declared but its value is never read.
const [summaryVideo, setSummaryVideo] = useRecoilState(summaryVideoState);

const callAPI = useCallback(async () => {
if (!videoId) return;

const searchParam = new URLSearchParams(search);
const isInsight = searchParam.get('insight') === 'true';

let isSuccess = false;
let result: IVideo | null = null;

try {
const { isSuccess, result } = (await getVideoAPI(videoId)).data;
if (isInsight) {
const { data } = await getDummyVideoAPI(videoId);

isSuccess = data.isSuccess;
result = data.result;
} else {
const { data } = await getVideoAPI(videoId);

isSuccess = data.isSuccess;
result = data.result;
}

if (!isSuccess) {
navigate('/');
return;
}

setSummaryVideo(result);
} catch (e) {
console.error(e);
navigate('/');
}
}, [videoId, navigate, setSummaryVideo]);
}, [search, videoId, navigate, setSummaryVideo]);

const setGuestSummaryVideo = () => {
if (!modelingData) {
navigate('/');
return;
}

const { subheading, tag, summary, ...others } = modelingData;

setSummaryVideo({
subHeading: subheading.map((item, id) => {
return { id, ...item };
}),
tag: tag.map((item, id) => {
return { id, ...item };
}),
summary: summary.map((item, id) => {
return { id, ...item };
}),
video_id: 0,
image: '',
...others,
});
};

useEffect(() => {
callAPI();
if (userToken) {
callAPI();
} else {
if (videoId === 'guest') {
setGuestSummaryVideo();
} else {
callAPI();
}
}

return () => {
setSummaryVideo(null);
// setModelingData(null);
};
}, [callAPI, setSummaryVideo]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [userToken]);

return (
<Container style={{ height: 'calc(100vh - 74px)' }}>
Expand Down
5 changes: 2 additions & 3 deletions src/stores/model-controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { atom } from 'recoil';

import { IVideo } from '@/models/video';
import { ModelingStatus } from '@/models/modeling';
import { ModelingFinalData, ModelingStatus } from '@/models/modeling';

import localStorageEffect from './effects/localStorageEffect';

Expand All @@ -20,7 +19,7 @@ export const modelingStatusState = atom<ModelingStatus>({
default: 'NONE',
});

export const modelingDataState = atom<IVideo | null>({
export const modelingDataState = atom<ModelingFinalData | null>({
key: 'modeling-data',
default: null,
effects_UNSTABLE: [localStorageEffect],
Expand Down
Loading

0 comments on commit 6a33fd0

Please sign in to comment.