Skip to content

Commit

Permalink
Merge branch 'dev' into feature-071
Browse files Browse the repository at this point in the history
  • Loading branch information
sehyun0518 committed Feb 19, 2024
2 parents e543d79 + b50a2e0 commit f44a048
Show file tree
Hide file tree
Showing 38 changed files with 615 additions and 444 deletions.
7 changes: 6 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
<div id="root"></div>

<script type="module" src="/src/main.tsx"></script>
<script src="https://developers.kakao.com/sdk/js/kakao.js"></script>
<script
src="https://developers.kakao.com/sdk/js/kakao.js"
async
defer
></script>
<script src="https://www.youtube.com/iframe_api" async defer></script>
</body>
</html>
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@types/jest": "^29.5.11",
"@types/node": "^20.11.17",
"@types/react-modal": "^3.16.3",
"@types/youtube": "^0.0.50",
"axios": "^1.6.4",
"lodash": "^4.17.21",
"react": "^18.2.0",
Expand Down
13 changes: 11 additions & 2 deletions src/apis/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import {
NickNameResponse,
FindEmailResponse,
FindEmailRequest,
CreateVideoAlarmRequest,
FindPasswordResponse,
FindPasswordRequest,
CreateVideoAlarmRequest
} from '@/models/user';
import {
AlarmResponse,
Expand Down Expand Up @@ -91,4 +93,11 @@ export const createVideoAlarmAPI = (
PREFIX + `/videoAlarm/${videoId}/${status}`,
data,
);
};
}

export const findPasswordAPI = (data : FindPasswordRequest) => {
return axios.post<FindPasswordResponse>(
PREFIX + '/findPassword',
data
);
}
5 changes: 5 additions & 0 deletions src/assets/icons/pause.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/success-mail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions src/components/FindPassword.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from "react"
import MailPng from '@/assets/mail.png';
import Container from "@/styles/FindEmail";
import { useNavigate } from "react-router-dom";

interface FindEmailProp {
email : string;
}

const FindPassword : React.FC<FindEmailProp> = ({email}) => {
const navigate = useNavigate();

const handleLoginBtn = () => {
navigate('/sign-in');
}
return(
<Container>
<div className="wrapper">
<div style={{gap : '15px'}}>
<img src={MailPng}/>
<center><span className="result">{email}<br /> 회원님의 임시 비밀번호를 전송하였습니다!</span></center>
<span className="tool">로그인하고 나만의 영상 아카이빙을 시작해요</span>
</div>
<div style={{gap : '10px'}}>
<button style={{backgroundColor : '#1E1E1E', color : '#FFFFFF'}} onClick={handleLoginBtn}>로그인 하러가기</button>
</div>
</div>
</Container>
);
}

export default FindPassword;
9 changes: 8 additions & 1 deletion src/components/Home/SearchYoutube.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ const SearchYoutube = ({ searchRef }: Props) => {
}
};

const handleChangeInput: React.ChangeEventHandler<HTMLInputElement> = (e) => {
setInputLink(e.target.value);
setVideoLink(null);
setStatus('NONE');
setProgress(0);
};

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

Expand Down Expand Up @@ -153,7 +160,7 @@ const SearchYoutube = ({ searchRef }: Props) => {
type="text"
value={inputLink}
disabled={status === 'CONTINUE'}
onChange={(e) => setInputLink(e.target.value)}
onChange={handleChangeInput}
placeholder="https://youtube.com/..."
/>
</div>
Expand Down
19 changes: 17 additions & 2 deletions src/components/NicknameModal.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
import styled from 'styled-components';
import theme from '@/styles/theme';
import React, { useState } from 'react';
import { nickNameAPI } from '@/apis/user';
import { getMyInfoAPI, nickNameAPI } from '@/apis/user';
import nameImg from '@/assets/name.png';
import { BlurBackground } from '@/styles/modals/common.style';
import { userInfoState } from '@/stores/user';
import { useSetRecoilState } from 'recoil';

const NicknameModal = () => {
const [inputCount, setInputCount] = useState(0);
const [name, setName] = useState<string>("");

const setUserInfo = useSetRecoilState(userInfoState);

const refreshMyInfo = async () => {
try {
const { result } = (await getMyInfoAPI()).data;

setUserInfo(result);
} catch (e) {
console.error(e);
}
}

const onChangeName = (e: React.ChangeEvent<HTMLInputElement>) => {
const target = e.currentTarget;
if (target.value.length > 7) {
target.value = target.value.slice(0, 7);
}
setName(target.value);
console.log(name);
setInputCount(
target.value.replace(/[\0-\x7f]|([0-\u07ff]|(.))/g, "$&$1$2").length
);
Expand All @@ -36,6 +49,7 @@ const NicknameModal = () => {
const response = (await nickNameAPI({
nick_name : name,
})).data
refreshMyInfo();
console.log(response);
} catch (err) {
console.log(err);
Expand Down Expand Up @@ -156,6 +170,7 @@ const SucButton = styled.button`
color: #fff;
text-align: center;
${theme.typography.Body1};
cursor: pointer;
`;

const Button = styled.button`
Expand Down
8 changes: 4 additions & 4 deletions src/components/SearchPage/SearchComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,18 @@ const SearchComponent : React.FC<TagInputProps> = ({tags, input, searchType, sel
if(!searchType){

if ((event.code === 'Comma' || event.code === 'Space') && !isComposing) {
event.preventDefault();
event.preventDefault();
if (input) {
tags.length > 0 && !input.startsWith('#') ? setTags([...tags, '#' + input]) : setTags([...tags, input])
if(selectedHashtags && setSelectedHashtags && !selectedHashtags.includes(input))
input.startsWith('#') ? setSelectedHashtags([...selectedHashtags, input.substring(1)]) : setSelectedHashtags([...selectedHashtags, input])
input.startsWith('#') ? setSelectedHashtags([...selectedHashtags, input.substring(1).replace(/\s/g, '')]) : setSelectedHashtags([...selectedHashtags, input.replace(/\s/g, '')])
setInput('');
}
} else if ((event.key === 'Backspace' || event.code === 'Backspace') && !input) {
if(tags.length > 0){
const lastValue = tags[tags.length - 1]
if(selectedHashtags && setSelectedHashtags && selectedHashtags.includes(lastValue.substring(1)))
setSelectedHashtags(selectedHashtags.filter((prev : string) => prev !== lastValue.substring(1)));
if(selectedHashtags && setSelectedHashtags && selectedHashtags.includes(lastValue.substring(1).replace(/\s/g, '')))
setSelectedHashtags(selectedHashtags.filter((prev : string) => prev !== lastValue.substring(1).replace(/\s/g, '')));
setRemovingTagIndex(tags.length - 1);

setTimeout(() => {
Expand Down
104 changes: 89 additions & 15 deletions src/components/SummaryPage/SummaryDetailBox/SummaryDetailBox.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { useRecoilState, useRecoilValue } from 'recoil';
import { useEffect, useRef } from 'react';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';

import { updateVideoCategoryIdAPI } from '@/apis/videos';

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

import {
summaryIsEditingViewState,
summaryPlaySubHeadingIdState,
summaryUpdateVideoState,
summaryVideoState,
summaryVideoTimeState,
} from '@/stores/summary';
import { toastListState } from '@/stores/toast';

Expand All @@ -24,9 +27,15 @@ type Props = {
};

const SummaryDetailBox = ({ onRefresh }: Props) => {
const player = useRef<YT.Player>();

const summaryVideo = useRecoilValue(summaryVideoState) as IVideo;
const summaryUpdateVideo = useRecoilValue(summaryUpdateVideoState);
const setSummaryVideoTime = useSetRecoilState(summaryVideoTimeState);
const isEditingView = useRecoilValue(summaryIsEditingViewState);
const [playSubHeadingId, setPlaySubHeadingId] = useRecoilState(
summaryPlaySubHeadingIdState,
);
const [toastList, setToastList] = useRecoilState(toastListState);

const subHeading = isEditingView
Expand All @@ -50,6 +59,75 @@ const SummaryDetailBox = ({ onRefresh }: Props) => {
}
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handleMessage = (e: any) => {
if (e.origin === 'https://www.youtube.com') {
try {
const { info } = JSON.parse(e.data);

if (!info) return;

setPlaySubHeadingId((id) => {
const item = subHeading.find((s) => s.id === id);

// END or PAUSE
if ([0, 2].includes(info.playerState)) {
return -1;
}

if (item) {
if (
item.start_time > info.currentTime ||
info.currentTime > item.end_time
)
return -1;
}

return id;
});

setSummaryVideoTime(info.currentTime);
} catch (e) {
console.error(e);
}
}
};

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

player.current = new YT.Player('player', {
videoId: summaryVideo.youtube_id,
});

window.onmessage = handleMessage;

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

useEffect(() => {
if (player.current) {
if (playSubHeadingId > -1) {
const item = subHeading.find((s) => s.id === playSubHeadingId);

if (item) {
player.current.seekTo(item.start_time, true);
player.current.playVideo();
}
} else if (playSubHeadingId === -2) {
// 영상 멈추기
player.current.pauseVideo();

setPlaySubHeadingId(-1);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [playSubHeadingId]);

return (
<div
style={{
Expand All @@ -73,19 +151,7 @@ const SummaryDetailBox = ({ onRefresh }: Props) => {
))}
</div>

<iframe
src={`https://www.youtube.com/embed/QXDiRtANAzA?${
isEditingView && 'start=10&end=18&autoplay=1&disablekb=0'
}`}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
style={{
margin: '20px 0',
width: '100%',
aspectRatio: '16 / 9',
borderRadius: 16,
}}
/>
<div id="player" />

<CategorySelectBox
disabled={isEditingView}
Expand All @@ -104,7 +170,15 @@ const SummaryDetailBox = ({ onRefresh }: Props) => {
}}
>
{subHeading.map((item, i) => (
<div key={item.id} className="subtitle">
<div
key={item.id}
className={`subtitle ${
playSubHeadingId > -1 &&
playSubHeadingId !== item.id &&
'disabled'
}`}
onClick={() => setPlaySubHeadingId(item.id)}
>
<span className="subtitle-index">{i + 1}</span>
<span className="subtitle-text">{item.name}</span>
</div>
Expand Down
Loading

0 comments on commit f44a048

Please sign in to comment.