-
Notifications
You must be signed in to change notification settings - Fork 2
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
feat: 트랙 추가하기 기능 구현 #419
feat: 트랙 추가하기 기능 구현 #419
Changes from all commits
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 |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { API } from "./axios"; | ||
|
||
// 트랙 생성 | ||
export const addTrack = async (projectId: string, params: {}) => { | ||
const url = `/projects/${projectId}/tracks`; | ||
const errorMessage = "트랙이 생성되지 않았습니다. 잠시 후 다시 시도해주세요."; | ||
|
||
try { | ||
const res = await API.post(url, params); | ||
return res.data; | ||
} catch (err) { | ||
console.log(err); | ||
alert(errorMessage); | ||
} | ||
|
||
return Promise.reject(new Error(errorMessage)); | ||
}; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -14,6 +14,7 @@ import UnderPlayBarViewModel from "viewmodel/UnderPlayBarViewModel"; | |||||||||||||||||||||
import useAudios from "hooks/useAudios"; | ||||||||||||||||||||||
import useTrackSetting from "hooks/useTrackSetting"; | ||||||||||||||||||||||
import useCreateTrack from "hooks/useCreateTrack"; | ||||||||||||||||||||||
import { NEW_TRACK_ID } from "constants/key"; | ||||||||||||||||||||||
|
||||||||||||||||||||||
import "./style.scss"; | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
@@ -22,20 +23,14 @@ interface ProjectInfoType { | |||||||||||||||||||||
bpmState: number; | ||||||||||||||||||||||
trackTags: Track[]; | ||||||||||||||||||||||
tracks: TrackResponseType[]; | ||||||||||||||||||||||
onTrackCreate: (title: string, trackTag: Track, audio: HTMLAudioElement) => void; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
function TrackSetting({ projectTitle, bpmState, trackTags, tracks }: ProjectInfoType) { | ||||||||||||||||||||||
const { | ||||||||||||||||||||||
inputDeviceId, | ||||||||||||||||||||||
inputTextDevice, | ||||||||||||||||||||||
trackTag, | ||||||||||||||||||||||
handleTitleInput, | ||||||||||||||||||||||
handleTrackTagSelect, | ||||||||||||||||||||||
handleDeviceClick, | ||||||||||||||||||||||
handleSettingSubmit, | ||||||||||||||||||||||
} = useTrackSetting(); | ||||||||||||||||||||||
function TrackSetting({ projectTitle, bpmState, trackTags, tracks, onTrackCreate }: ProjectInfoType) { | ||||||||||||||||||||||
const { title, inputDeviceId, inputTextDevice, trackTag, handleTitleInput, handleTrackTagSelect, handleDeviceClick } = | ||||||||||||||||||||||
useTrackSetting(); | ||||||||||||||||||||||
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. prettier가 이렇게 포맷팅 시켜주나요?? 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. 네! printWidth를 120으로 설정해둬서 그런가봐요..😂 |
||||||||||||||||||||||
|
||||||||||||||||||||||
const { setAudios, addAudio, removeAudio } = useAudios(); | ||||||||||||||||||||||
const { audioList, setAudios, addAudio, removeAudio } = useAudios(); | ||||||||||||||||||||||
|
||||||||||||||||||||||
const { isRecording, isRecordSuccess, handleRecordButtonClick, handleTrackRemove } = useCreateTrack({ | ||||||||||||||||||||||
inputDeviceId, | ||||||||||||||||||||||
|
@@ -49,6 +44,16 @@ function TrackSetting({ projectTitle, bpmState, trackTags, tracks }: ProjectInfo | |||||||||||||||||||||
}, | ||||||||||||||||||||||
}); | ||||||||||||||||||||||
|
||||||||||||||||||||||
const handleTrackSubmit = () => { | ||||||||||||||||||||||
const recordedAudio = audioList.find(({ id }) => id === NEW_TRACK_ID); | ||||||||||||||||||||||
|
||||||||||||||||||||||
if (!title || !trackTag || !recordedAudio) { | ||||||||||||||||||||||
return; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
Comment on lines
+50
to
+52
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. 제목, 태그, 녹음에 대한 사용자 액션을 유도하는 얼럿을 추가해주는 것은 어떨까요??
Suggested change
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. 오.. 이렇게 required 요소를 체크하는 방법 좋은 것 같아요! 👍🏻 |
||||||||||||||||||||||
|
||||||||||||||||||||||
onTrackCreate(title, trackTag, recordedAudio.audio); | ||||||||||||||||||||||
}; | ||||||||||||||||||||||
|
||||||||||||||||||||||
useEffect(() => { | ||||||||||||||||||||||
if (tracks.length === 0) { | ||||||||||||||||||||||
return; | ||||||||||||||||||||||
|
@@ -72,7 +77,7 @@ function TrackSetting({ projectTitle, bpmState, trackTags, tracks }: ProjectInfo | |||||||||||||||||||||
<RecordDevice onDeviceClick={handleDeviceClick} inputTextDevice={inputTextDevice} /> | ||||||||||||||||||||||
<TrackTag onTrackClick={handleTrackTagSelect} selectedTrack={trackTag} tracks={trackTags} /> | ||||||||||||||||||||||
</div> | ||||||||||||||||||||||
<Button type="green" onBtnClick={handleSettingSubmit} marginTop="4rem" width="100%"> | ||||||||||||||||||||||
<Button type="green" onBtnClick={handleTrackSubmit} marginTop="4rem" width="100%"> | ||||||||||||||||||||||
트랙 추가하기 | ||||||||||||||||||||||
</Button> | ||||||||||||||||||||||
</div> | ||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,20 +1,44 @@ | ||||||||||||||||||||||||||
import { useEffect, useState } from "react"; | ||||||||||||||||||||||||||
import { useParams } from "react-router-dom"; | ||||||||||||||||||||||||||
import { useNavigate, useParams } from "react-router-dom"; | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
import { ProjectResponseType } from "types/projectType"; | ||||||||||||||||||||||||||
import { ProjectResponseType, Track } from "types/projectType"; | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
import { getProject } from "api/project"; | ||||||||||||||||||||||||||
import { addTrack } from "api/track"; | ||||||||||||||||||||||||||
import { trackList as TrackTags } from "utils/data/track"; | ||||||||||||||||||||||||||
import { getAudioBlob } from "utils/audio"; | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
import TrackSetting from "components/blocks/TrackSetting"; | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
function CreateTrackViewModel() { | ||||||||||||||||||||||||||
const { projectId } = useParams(); | ||||||||||||||||||||||||||
const navigate = useNavigate(); | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
const [projectInfo, setProjectInfo] = useState<ProjectResponseType>(); | ||||||||||||||||||||||||||
const [isLoading, setIsLoading] = useState(false); | ||||||||||||||||||||||||||
const isFetched = !isLoading && projectInfo; | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
// 트랙 생성하기 버튼 클릭 | ||||||||||||||||||||||||||
const handleTrackCreate = (title: string, trackTag: Track, audio: HTMLAudioElement) => { | ||||||||||||||||||||||||||
if (!projectId) { | ||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
const createTrack = async () => { | ||||||||||||||||||||||||||
const recordedBlob = await getAudioBlob(audio); | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
const formData = new FormData(); | ||||||||||||||||||||||||||
formData.append("trackName", title); | ||||||||||||||||||||||||||
formData.append("trackTag", trackTag); | ||||||||||||||||||||||||||
formData.append("audioFile", recordedBlob); | ||||||||||||||||||||||||||
Comment on lines
+28
to
+33
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. 인스턴스 생성 구끼리 인접하게 두는게 더 깔끔해보일 것 같아요ㅎㅎ
Suggested change
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. 저는 코드를 읽을 때 formData를 생성하는 부분이 한 블록으로 읽히면 좋을 것 같아서 묶어뒀어요. 저도 변수 선언부가 인접해있으면 깔끔하다는 의견에 동의해요! 👍🏻 |
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
await addTrack(projectId, formData); | ||||||||||||||||||||||||||
navigate(`/${projectId}`); | ||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
createTrack(); | ||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
useEffect(() => { | ||||||||||||||||||||||||||
if (!projectId) { | ||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||
|
@@ -38,6 +62,7 @@ function CreateTrackViewModel() { | |||||||||||||||||||||||||
projectTitle={projectInfo.projectName} | ||||||||||||||||||||||||||
bpmState={projectInfo.bpm} | ||||||||||||||||||||||||||
tracks={projectInfo.tracks} | ||||||||||||||||||||||||||
onTrackCreate={handleTrackCreate} | ||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||
) : ( | ||||||||||||||||||||||||||
<div>Loading...</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.
params에 빈 객체로 타입을 설정하면 addTrack 호출부에서 params에 key 넣을 때 타입에러가 뜨진 않나요??
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.
FormData 타입이 빈 객체로 정의되어 있어서 에러가 발생하지는 않는 것으로 보여요. 이전 프로젝트 생성할 때 작성했던 코드를 재사용하다가 parameter 타입을 놓쳤네요.. 여기선
FormData
타입을 사용하는게 더 정확할 것 같아요!