-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Post video #19
Post video #19
Changes from all commits
d278a76
a93bb6d
1461a62
4f182b6
c829f6e
6cf4eaf
b56b1d7
40f1bba
b2c9c34
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,40 @@ | ||
import React, { useEffect, useState } from "react"; | ||
import AddVideoHook from "../../../hooks/AddVideo"; | ||
|
||
import AddVideoModal from "./AddVideoModal"; | ||
import GetLogin from "../../../hooks/GetLogin"; | ||
import { FaTimes } from 'react-icons/fa'; | ||
import "./AddVideo.css"; | ||
import { Redirect } from "react-router-dom"; | ||
import { postVideo } from "../../../api/addVideo"; | ||
import { maxTagCount, maxTagLength, titleMaxLength, titleMinLength, descriptionMaxLength, tagAllowedPattern } from "../../../constant/Addvideo"; | ||
|
||
const getYoutubeThumbnailUrl = (id: string) => { | ||
return `https://img.youtube.com/vi/${id}/0.jpg`; | ||
const getYoutubeiframe = (id: string) => ( | ||
<iframe src={`https://www.youtube.com/embed/${id}`} | ||
frameBorder='0' | ||
allow='autoplay; encrypted-media' | ||
allowFullScreen | ||
title='video' | ||
className='add-video-youtube-video' | ||
/> | ||
); | ||
const setYoutubeId = (id: string) => { | ||
return `https://www.youtube.com/watch?v=${id}` | ||
} | ||
const maxTagCount = 5; | ||
|
||
const AddVideo: React.FC = () => { | ||
const { userInfo } = GetLogin(); | ||
const { id, url, title, description, tags, init, setUrl, setTitle, setDescription, addTag, deleteTag } = AddVideoHook(); | ||
const [tag, setTag] = useState(""); | ||
|
||
// mount될 때만 init함수가 실행되도록 하고 싶어서 lint warning을 없앴습니다. | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
useEffect(init, []); | ||
|
||
// TODO: implement debounce | ||
if(userInfo == null) { | ||
alert("로그인이 필요한 페이지입니다."); | ||
return <Redirect to="/"/>; | ||
} | ||
|
||
const handleUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||
setUrl(e.target.value); | ||
}; | ||
|
@@ -31,7 +47,7 @@ const AddVideo: React.FC = () => { | |
|
||
// is memoization needed? | ||
const thumbnailView = (id != "") ? (<div className="add-video-thumbnail-container"> | ||
<img src={getYoutubeThumbnailUrl(id)} /> | ||
{getYoutubeiframe(id)} | ||
</div>) : (<div className="add-video-thumbnail-container"> | ||
<div> | ||
<FaTimes className="add-video-thumbnail-times" /> | ||
|
@@ -72,18 +88,31 @@ const AddVideo: React.FC = () => { | |
if(tag == "") { | ||
return; | ||
} | ||
if(!tagAllowedPattern.test(tag)) { | ||
alert("태그에는 한글, 영어, 숫자만 입력 가능합니다."); | ||
return; | ||
} | ||
if(tag.length >= maxTagLength) { | ||
alert(`한 태그의 길이는 ${maxTagLength}자까지 가능합니다.`); | ||
return; | ||
} | ||
if(tags.some((val) => (val==tag))) { | ||
alert("같은이름의 태그가 존재합니다."); | ||
return; | ||
} | ||
if(tags.length >= maxTagCount) { | ||
alert("태그는 5개까지 등록이 가능합니다."); | ||
alert(`태그는 ${maxTagCount}개까지 등록이 가능합니다.`); | ||
return; | ||
} | ||
addTag(tag); | ||
setTag(""); | ||
} | ||
} | ||
|
||
const setVideo = (id: string) => { | ||
setUrl(setYoutubeId(id)); | ||
} | ||
|
||
const tagsInput = ( | ||
<div className="add-video-input-container"> | ||
<span className="badge bg-primary">태그</span> | ||
|
@@ -97,8 +126,35 @@ const AddVideo: React.FC = () => { | |
</div>); | ||
}; | ||
|
||
const handleSubmit = async (): Promise<void> => { | ||
if(id == "") { | ||
alert("정상적인 유튜브 동영상을 입력해주세요."); | ||
return; | ||
} | ||
if(title == "") { | ||
alert("제목이 없습니다."); | ||
return; | ||
} | ||
if(title.length < titleMinLength || title.length > titleMaxLength) { | ||
alert(`제목은 ${titleMinLength}~${titleMaxLength}자까지 가능합니다.`); | ||
return; | ||
} | ||
if(description.length > descriptionMaxLength) { | ||
alert(`설명은 ${descriptionMaxLength}자까지 가능합니다.`); | ||
return; | ||
} | ||
|
||
const ok = await postVideo(id, title, description, tags); | ||
if(!ok) { | ||
alert("알 수 없는 에러가 발생하였습니다."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. API 에서 실패 원인을 내려주긴하는데 실패 원인을 보여줄 수 있으면 좋을 것 같습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 해당 API에서는 input validation을 통과하지 못하면 400 에러가 나는데, client-side에서도 validation을 체크한 상태여서 현재는 딱히 에러를 표시할게 없습니다. 이슈 등록해두고 추후에 에러코드가 다양해지면 수정하겠습니다. |
||
return; | ||
} | ||
|
||
alert("gooood"); | ||
} | ||
|
||
return (<div className="add-video-container"> | ||
<AddVideoModal /> | ||
<AddVideoModal setVideo={setVideo}/> | ||
{urlInput} | ||
{thumbnailView} | ||
{titleInput} | ||
|
@@ -107,7 +163,7 @@ const AddVideo: React.FC = () => { | |
<div className="add-video-tags-container"> | ||
{tags.map((tag, idx) => tagInput(tag, idx))} | ||
</div> | ||
<button type="button" className="btn btn-success add-video-submit-button">등록</button> | ||
<button type="button" className="btn btn-success add-video-submit-button" onClick={handleSubmit}>등록</button> | ||
</div>); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기서 addTag 한 이후에 다른페이지를 갔다가 다시 영상 추가 페이지로 이동할 시, tag들만 그대로 남아있는 문제가 있습니다. 영상 등록 성공 후에는 모든 제목, 영상 url, tag, 설명 등을 지워주는 로직을 추가하면 좋을 것 같습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수정했습니다.