-
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/#499 등록 ui 개선 및 등록 페이지 리팩터링 #508
Merged
Merged
Changes from all commits
Commits
Show all changes
98 commits
Select commit
Hold shift + click to select a range
10bd732
feat: waveScrubber ui 구현
ukkodeveloper 7d55392
refactor: wave ui 별도의 컴포넌트로 분리
ukkodeveloper c973da2
refactor: useDebounceEffect deps 인자 타입 배열로 수정
ukkodeveloper 6be7ada
refactor: WaveScrubber 이벤트 핸들러 등 리팩터링
ukkodeveloper 436abdb
fix: PlayerState enum 제거
ukkodeveloper 9e2cfd5
feat: 킬링파트 interval 5~15초로 변경
ukkodeveloper 913e23b
design: 슬라이더 디자인 수정
ukkodeveloper f08767c
design: ios 환경을 고려하여 100vh 적용을 위해 layout 수정
ukkodeveloper b2af6e2
design: Thumbnail size sm 추가
ukkodeveloper 3e58646
design: Collecting Page 전반적인 디자인 수정
ukkodeveloper aa0b9a7
feat: badge component 구현
ukkodeveloper 905d31e
feat: progress bar 수정 및 전체 재생 progress bar 구현
ukkodeveloper be1a18a
design: VoteInterface 상하 간격 조정
ukkodeveloper 228ceac
design: 버튼 및 scrubber 사용 시 디자인 추가
ukkodeveloper 6b939c5
feat: 각종 등록 관련 제어 태그 추가
ukkodeveloper 2e1795b
fix: WaveScrubber 정지 오류 및 터치 시 재생 오류 수정
ukkodeveloper 0cd252e
design: body background black으로 하여 스크롤 끝에 흰색 나오지 않도록 수정
ukkodeveloper 607ec8f
design: register 버튼 디자인 수정
ukkodeveloper e054219
fix: 파트 등록 페이지에 AuthLayout 재적용
ukkodeveloper e00119b
refactor: 시작, 정지 버튼 별도의 컴포넌트로 분리
ukkodeveloper eb8e960
refactor: Flex 컴포넌트 사용하여 WaveScrubber 리팩터링
ukkodeveloper 709cdd5
feat: 킬링파트 등록하는 페이지 반응형 구현
ukkodeveloper bd956bd
feat: 유튜브 재생 effect 의존성 배열에 플레이어 상태 추가
ukkodeveloper 8db7a4c
design: 사용하지 않는 속성 제거 및 css 속성 수정
ukkodeveloper 8b2ff86
style: styled lint 적용
ukkodeveloper 251865d
refactor: WaveScrubber 구현에 있어 필요없는 컴포넌트 삭제 및 한 데 두기
ukkodeveloper 3be1447
refactor: video 재생 관련 badge 정보들 컴포넌트로 뭉치기
ukkodeveloper 271da9a
refactor: 구간 초 설정하는 컴포넌트 반복 제거 및 스타일 수정
ukkodeveloper 0d83fa9
refactor: 페이지 파트 정하기 안내 메세지 컴포넌트로 분리
ukkodeveloper b85f8b8
refactor: 등록 요청하는 컴포넌트 분리
ukkodeveloper dfa6528
refactor: 앨범 자켓, 가수, 제목 컨텐츠를 컴포넌트로 분리
ukkodeveloper ed1a762
refactor: 비디어를 제어하고 파트를 고르는 컴포넌트 분리
ukkodeveloper 7ec406c
feat: 페이지 단에서 컴포넌트 위계가 보이도록 수정
ukkodeveloper 7780231
design: 데스크탑 사이즈에서 버튼 하단에 오도록 수정
ukkodeveloper 598fe13
design: flex 및 컴포넌트 container 디자인 세부 수정
ukkodeveloper 20e8cdf
design: 긴 글자 올 경우 대비하여 수정
ukkodeveloper 71f5453
chore: 사용하지 않는 컴포넌트 삭제
ukkodeveloper 318b79b
refactor: hook 정리 및 이름 변경
ukkodeveloper f4f6145
feat: 웹 접근성 및 시멘틱 태그 적용
ukkodeveloper ac59d22
fix: 등록 공유 url 수정
ukkodeveloper bd026d0
design: theme에 마젠타 색 팔레트 추가 및 적용
ukkodeveloper 225a688
refactor: Player 상태 enum값 적용 및 관련 함수명 변경
ukkodeveloper df40820
style: style lint 적용
ukkodeveloper a1f8881
refactor: Flex suffix로 통일
ukkodeveloper c32c44d
refactor: color theme 적용
ukkodeveloper 676ad40
fix: 컴포넌트 레이아웃 유튜브, 컨트롤러 부분 속성 변경
ukkodeveloper b9f75b9
feat: 프로그레스 바 부드럽게 사용할 수 있도록 수정
ukkodeveloper 192451b
fix: 재생, 정지버튼 계속 깜빡거리는 문제 해결
ukkodeveloper 1f72890
fix: Fragment에 key 추가
ukkodeveloper 78eead5
design: HeaderSpacing 추가 및 페이지 패딩 수정
ukkodeveloper 3784a9a
chore: 파트 등록 관련 모듈 킬링파트 디렉터리로 이동
ukkodeveloper adf5d4c
refactor: interval 상태변경 훅 코드 개선
ukkodeveloper b63c47e
design: desktop 기준 padding 16px 적용
ukkodeveloper ee81ed7
refactor: useDebounceEffect 훅으로 변경
ukkodeveloper f681587
fix: page translateY 제거
ukkodeveloper ce3d7c1
fix: 전체듣기 toggle 해제 시에 구간 첫 시작으로 이동
ukkodeveloper 9800dca
fix: 10초뒤에 자동시작되는 현상
ukkodeveloper 7c4d0d7
feat: 마우스 휠로 scrubber 탐색할 수 있도록 이벤트 추가
ukkodeveloper 22c605f
fix: 너비에 맞게 시간 초 계산할 수 있도록 수정
ukkodeveloper d15f4bf
feat: 구간 길이에 따라서 progress bar 길이 변경
ukkodeveloper f7b923f
feat: Youtube 조작 여부 props로 추가 및 적용
ukkodeveloper 4225145
feat: 데스크탑 환경에서 소제목 제공
ukkodeveloper 482ca98
feat: waveScrubber 드래그 이동 추가
ukkodeveloper 33e8f6a
design: 전반적인 페이지 내 폰트 크기 등 디자인 수정
ukkodeveloper c6df2b8
feat: wave interaction 추가. 사용성 개선
ukkodeveloper 92e7542
fix: waveScrubber interval 조절 시 시작점 스크롤 문제 해결
ukkodeveloper ef4142e
feat: 변경된 명세 반영
ukkodeveloper a4f1934
design: 소제목 폰트 사이즈 변경
ukkodeveloper dcd0b5e
design: 데스크탑 환경에서 waveScrubber 높이 증가하여 변경
ukkodeveloper c1dfbb1
refactor: useWave 훅 분리
ukkodeveloper 6505614
design: stepper 버튼 크기 조절 및 스크롤 디자인 수정
ukkodeveloper f1a42ff
feat: song 조회 명세 변경에 따른 변경
ukkodeveloper 9a490d8
chore: 페이지 내에서 사용될 svg 파일 추가
ukkodeveloper dd52fc7
fix: 영상 끊김 현상으로 인해 debounce 길이 연장
ukkodeveloper 92afe46
feat: 등록 시간 임시 저장할 수 있도록 pin 기능 추가
ukkodeveloper c3711ba
refactor: pin 관련 상태 네이밍 변경
ukkodeveloper 89b2b9c
design: 상하 간격 추가
ukkodeveloper 69e4614
fix: 핀 active 상태를 데이터 중심으로 변경
ukkodeveloper ad9a407
refactor: usePin 분리
ukkodeveloper 44fd17a
feat: 등록 시에 이전 페이지 이동 및 모달 수정
ukkodeveloper 1f22eca
design: pin 디자인 수정
ukkodeveloper 7251648
fix: pin 변경 시 스크롤 연동되지 않는 현상 수정
ukkodeveloper d119c11
design: 안내 메세지 삭제로 인한 전반적인 높이 수정
ukkodeveloper e77d50a
refactor: soundwave active 높이변경 함수의 이름 변경
ukkodeveloper 7065662
style: styled lint 적용
ukkodeveloper 615cb57
style: 사용하지 않는 css 속성 제거
ukkodeveloper f21a517
refactor: ref 이름 명확하게 변경
ukkodeveloper c4c16f1
Merge branch 'main' into feat/#499
ukkodeveloper 572d1b8
fix: useDebounceEffect 변경사항 적용
ukkodeveloper 07bb3a1
refactor: 조기 리턴으로 로직 변경
ukkodeveloper 6825ec0
fix: 내 파트 등록 시에 비디오 정지되도록 수정
ukkodeveloper 63a8bcc
style: WaveWrapper props 순서 변경
ukkodeveloper f2baad4
style: SoundWave ref lint 에러 수정
ukkodeveloper 50b2a2e
Merge branch 'main' into feat/#499
ukkodeveloper 955b6d3
feat: pin 및 SoundWave 사용성 개선
ukkodeveloper 5b8d48b
feat: SoundWave 이동 시에 pin 클릭 이벤트 방지
ukkodeveloper 2634432
feat: 스크롤 중 유튜브 재생 정지 방지
ukkodeveloper 0e55af8
Merge branch 'main' into feat/#499
ukkodeveloper File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
130 changes: 130 additions & 0 deletions
130
frontend/src/features/killingParts/components/RegisterPart.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import { useNavigate } from 'react-router-dom'; | ||
import styled from 'styled-components'; | ||
import { useAuthContext } from '@/features/auth/components/AuthProvider'; | ||
import useCollectingPartContext from '@/features/killingParts/hooks/useCollectingPartContext'; | ||
import { usePostKillingPart } from '@/features/killingParts/remotes/usePostKillingPart'; | ||
import useVideoPlayerContext from '@/features/youtube/hooks/useVideoPlayerContext'; | ||
import useModal from '@/shared/components/Modal/hooks/useModal'; | ||
import Modal from '@/shared/components/Modal/Modal'; | ||
import Spacing from '@/shared/components/Spacing'; | ||
import { toPlayingTimeText } from '@/shared/utils/convertTime'; | ||
|
||
const RegisterPart = () => { | ||
const { isOpen, openModal, closeModal } = useModal(); | ||
const { user } = useAuthContext(); | ||
const { interval, partStartTime, songId } = useCollectingPartContext(); | ||
const video = useVideoPlayerContext(); | ||
const { createKillingPart } = usePostKillingPart(); | ||
const navigate = useNavigate(); | ||
|
||
// 현재 useMutation 훅이 response 객체를 리턴하지 않고 내부적으로 처리합니다. | ||
// 때문에 컴포넌트 단에서 createKillingPart 성공 여부에 따라 등록 완료 만료를 처리를 할 수 없어요! | ||
// 현재 비로그인 시에 등록을 누르면 두 개의 모달이 뜹니다.정 | ||
const submitKillingPart = async () => { | ||
await createKillingPart(songId, { startSecond: partStartTime, length: interval }); | ||
navigate(-1); | ||
}; | ||
|
||
const openRegisterModal = () => { | ||
video.pause(); | ||
openModal(); | ||
}; | ||
|
||
const voteTimeText = toPlayingTimeText(partStartTime, partStartTime + interval); | ||
|
||
return ( | ||
<> | ||
<RegisterButton onClick={openRegisterModal}>등록</RegisterButton> | ||
<Modal isOpen={isOpen} closeModal={closeModal}> | ||
<ModalTitle> | ||
<TitleColumn>{user?.nickname}님의 파트 저장</TitleColumn> | ||
</ModalTitle> | ||
<ModalContent> | ||
<Message> | ||
<Part>{voteTimeText}</Part> | ||
</Message> | ||
<Spacing direction="vertical" size={6} /> | ||
<Message>나만의 파트로 등록하시겠습니까?</Message> | ||
</ModalContent> | ||
<ButtonContainer> | ||
<Cancel type="button" onClick={closeModal}> | ||
취소 | ||
</Cancel> | ||
<Confirm type="button" onClick={submitKillingPart}> | ||
등록 | ||
</Confirm> | ||
</ButtonContainer> | ||
</Modal> | ||
</> | ||
); | ||
}; | ||
|
||
export default RegisterPart; | ||
|
||
const RegisterButton = styled.button` | ||
width: 100%; | ||
margin-top: auto; | ||
padding: 8px 11px; | ||
|
||
font-weight: 700; | ||
color: ${({ theme: { color } }) => color.white}; | ||
letter-spacing: 6px; | ||
|
||
background-color: ${({ theme: { color } }) => color.primary}; | ||
border-radius: 6px; | ||
|
||
@media (min-width: ${({ theme }) => theme.breakPoints.md}) { | ||
padding: 11px 15px; | ||
|
||
font-size: 18px; | ||
} | ||
`; | ||
|
||
const ModalTitle = styled.h3``; | ||
|
||
const TitleColumn = styled.div` | ||
text-align: center; | ||
`; | ||
|
||
const ModalContent = styled.div` | ||
padding: 16px 0; | ||
|
||
font-size: 16px; | ||
color: #b5b3bc; | ||
text-align: center; | ||
white-space: pre-line; | ||
`; | ||
|
||
const Message = styled.div``; | ||
|
||
const Button = styled.button` | ||
height: 36px; | ||
color: ${({ theme: { color } }) => color.white}; | ||
border-radius: 10px; | ||
`; | ||
|
||
const Cancel = styled(Button)` | ||
flex: 1; | ||
background-color: ${({ theme: { color } }) => color.secondary}; | ||
`; | ||
|
||
const Confirm = styled(Button)` | ||
flex: 1; | ||
background-color: ${({ theme: { color } }) => color.primary}; | ||
`; | ||
|
||
const ButtonContainer = styled.div` | ||
display: flex; | ||
gap: 16px; | ||
width: 100%; | ||
`; | ||
|
||
const Part = styled.span` | ||
padding: 6px 11px; | ||
|
||
color: white; | ||
letter-spacing: 1px; | ||
|
||
background-color: ${({ theme: { color } }) => color.disabled}; | ||
border-radius: 10px; | ||
`; |
63 changes: 63 additions & 0 deletions
63
frontend/src/features/killingParts/components/SoundWave.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import React, { forwardRef } from 'react'; | ||
import styled from 'styled-components'; | ||
|
||
interface SoundWaveProps { | ||
length: number; | ||
progressWidth: number; | ||
} | ||
|
||
const SoundWave = forwardRef<HTMLDivElement, SoundWaveProps>( | ||
({ length, progressWidth }, boxRef) => { | ||
const stretchWaveHeight = | ||
(activeHeight: string, inactiveHeight: string) => (dom: HTMLDivElement | null) => { | ||
if (!dom || !boxRef || typeof boxRef === 'function' || !boxRef.current?.scrollLeft) return; | ||
|
||
const boxPos = | ||
boxRef.current?.scrollLeft + boxRef.current?.clientWidth / 2 - progressWidth / 2; | ||
|
||
const containerRightEdge = boxPos + progressWidth; | ||
const itemRightEdge = dom.offsetLeft; | ||
|
||
if (itemRightEdge >= boxPos && itemRightEdge <= containerRightEdge) { | ||
dom.style.height = activeHeight; | ||
} else { | ||
dom.style.height = inactiveHeight; | ||
} | ||
}; | ||
|
||
return Array.from({ length }, (_, index) => ( | ||
<React.Fragment key={index}> | ||
<LongBar ref={stretchWaveHeight('25px', '20px')} /> | ||
<ShortBar ref={stretchWaveHeight('17px', '12px')} /> | ||
</React.Fragment> | ||
)); | ||
} | ||
); | ||
|
||
SoundWave.displayName = 'SoundWave'; | ||
export default SoundWave; | ||
|
||
const LongBar = styled.div` | ||
z-index: 2; | ||
left: 50%; | ||
|
||
width: 4px; | ||
height: 24px; | ||
|
||
background-color: ${({ theme: { color } }) => color.white}; | ||
border-radius: 5px; | ||
|
||
transition: height 0.2s ease; | ||
`; | ||
|
||
const ShortBar = styled.div` | ||
z-index: 2; | ||
|
||
width: 4px; | ||
height: 15px; | ||
|
||
background-color: ${({ theme: { color } }) => color.white}; | ||
border-radius: 5px; | ||
|
||
transition: height 0.2s ease; | ||
`; |
185 changes: 185 additions & 0 deletions
185
frontend/src/features/killingParts/components/VideoBadges.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
import styled, { css, keyframes } from 'styled-components'; | ||
import playIcon from '@/assets/icon/fill-play.svg'; | ||
import pauseIcon from '@/assets/icon/pause.svg'; | ||
import pinIcon from '@/assets/icon/pin.svg'; | ||
import playStreamIcon from '@/assets/icon/play-stream.svg'; | ||
import removeIcon from '@/assets/icon/remove.svg'; | ||
import useCollectingPartContext from '@/features/killingParts/hooks/useCollectingPartContext'; | ||
import usePin from '@/features/killingParts/hooks/usePin'; | ||
import useVideoPlayerContext from '@/features/youtube/hooks/useVideoPlayerContext'; | ||
import Flex from '@/shared/components/Flex/Flex'; | ||
import { toMinSecText } from '@/shared/utils/convertTime'; | ||
|
||
const VideoBadges = () => { | ||
const { partStartTime, isPlayingEntire, scrollingRef, toggleEntirePlaying } = | ||
useCollectingPartContext(); | ||
const { | ||
pinList, | ||
isPinListEmpty, | ||
activePinIndex, | ||
pinContainerRef, | ||
pinAnimationRef, | ||
addPin, | ||
deletePin, | ||
playPin, | ||
} = usePin(); | ||
const video = useVideoPlayerContext(); | ||
|
||
const partStartTimeText = toMinSecText(partStartTime); | ||
const isPaused = video.playerState === YT.PlayerState.PAUSED; | ||
const videoPlay = () => { | ||
if (isPlayingEntire) { | ||
video.play(); | ||
} else { | ||
video.seekTo(partStartTime); | ||
} | ||
}; | ||
|
||
const videoPause = () => { | ||
if (scrollingRef.current === null) { | ||
video.pause(); | ||
} | ||
}; | ||
|
||
return ( | ||
<> | ||
<Flex $gap={14} $justify="flex-end"> | ||
<StartBadge> | ||
<img src={playStreamIcon} style={{ marginRight: '4px' }} alt="" /> | ||
{partStartTimeText} | ||
</StartBadge> | ||
<Badge as="button" onClick={addPin} $isActive={!isPinListEmpty}> | ||
<img src={pinIcon} alt="나만의 파트 임시 저장" /> | ||
</Badge> | ||
<Badge as="button" type="button" onClick={isPaused ? videoPlay : videoPause}> | ||
<img src={isPaused ? playIcon : pauseIcon} alt={'재생 혹은 정지'} /> | ||
</Badge> | ||
<Badge as="button" type="button" $isActive={isPlayingEntire} onClick={toggleEntirePlaying}> | ||
전체 듣기 | ||
</Badge> | ||
</Flex> | ||
<PinFlex $gap={4} ref={pinContainerRef}> | ||
{!isPinListEmpty && ( | ||
<DeleteBadge as="button" onClick={deletePin}> | ||
<img src={removeIcon} alt="나만의 파트 임시 저장 삭제하기" /> | ||
</DeleteBadge> | ||
)} | ||
<PinInner $gap={4} ref={pinContainerRef}> | ||
{pinList.map((pin, index) => ( | ||
<PinBadge | ||
key={pin.text + pinAnimationRef.current} | ||
as="button" | ||
onClick={playPin(pin.partStartTime, pin.interval)} | ||
$isActive={index === activePinIndex} | ||
$isNew={index === 0} | ||
> | ||
{pin.text} | ||
</PinBadge> | ||
))} | ||
</PinInner> | ||
</PinFlex> | ||
</> | ||
); | ||
}; | ||
export default VideoBadges; | ||
|
||
const PinFlex = styled(Flex)` | ||
width: 100%; | ||
`; | ||
|
||
const PinInner = styled(Flex)` | ||
overflow-x: scroll; | ||
width: calc(100% - 44px); | ||
`; | ||
|
||
const Badge = styled.span<{ $isActive?: boolean }>` | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
|
||
min-width: 40px; | ||
height: 30px; | ||
padding: 0 10px; | ||
|
||
font-size: 14px; | ||
color: ${({ theme: { color } }) => color.white}; | ||
text-align: center; | ||
|
||
background-color: ${({ theme: { color }, $isActive }) => | ||
$isActive ? color.magenta700 : color.disabled}; | ||
border-radius: 40px; | ||
|
||
transition: | ||
background-color 0.2s ease-in, | ||
box-shadow 0.2s ease; | ||
|
||
&:active { | ||
box-shadow: 0 0 0 1px inset white; | ||
} | ||
|
||
@media (min-width: ${({ theme }) => theme.breakPoints.md}) { | ||
font-size: 16px; | ||
} | ||
`; | ||
|
||
const StartBadge = styled(Badge)` | ||
margin-right: auto; | ||
letter-spacing: 1px; | ||
`; | ||
|
||
const slideFirstItem = keyframes` | ||
from { | ||
opacity: 0; | ||
transform: translateX(-30px); | ||
|
||
} | ||
to { | ||
opacity: 1; | ||
transform: translateX(0); | ||
} | ||
`; | ||
|
||
const slideRestItems = keyframes` | ||
from { | ||
transform: translateX(-15px); | ||
} | ||
to { | ||
transform: translateX(0); | ||
} | ||
`; | ||
|
||
const PinBadge = styled(Badge)<{ $isActive?: boolean; $isNew?: boolean }>` | ||
z-index: ${({ $isActive }) => ($isActive ? 1 : 0)}; | ||
|
||
width: 50px; | ||
margin-right: 4px; | ||
|
||
font-size: 12px; | ||
color: black; | ||
white-space: nowrap; | ||
|
||
opacity: ${({ $isActive }) => ($isActive ? 1 : 0.5)}; | ||
background-color: ${({ theme: { color }, $isActive }) => | ||
$isActive ? color.magenta700 : color.disabledBackground}; | ||
border: none; | ||
border-radius: 4px; | ||
|
||
transition: background-color 0.3s ease-in-out; | ||
animation: ${({ $isNew }) => | ||
$isNew | ||
? css` | ||
${slideFirstItem} 0.6s forwards | ||
` | ||
: css` | ||
${slideRestItems} 0.3s forwards | ||
`}; | ||
`; | ||
|
||
const DeleteBadge = styled(Badge)` | ||
min-width: 30px; | ||
height: 30px; | ||
margin-right: 10px; | ||
padding: 0; | ||
|
||
border-radius: 50%; | ||
`; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
💬 -1 은 뒤로가기의 의미이니 '듣기 페이지로 이동' 이라는 의미를 조금 더 확실히 해주면 어떨까요?
💬 추가로 -1은 어떤 페이지에서 접속하든 이전 히스토리로 이동하기 때문에, 이에대한 이슈도 있을 것 같아요.
songId도 사용할 수 있으니 명시해도 좋을 것 같아요.
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.
장르는 ALL 때릴생각을 하고 이야기했었는데, 우코의 생각이 더 좋은것 같아요! ㅎㅎ
대화를 통해 해결했습니다~
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.
[대화 정리]