-
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
Changes from 55 commits
10bd732
7d55392
c973da2
6be7ada
436abdb
9e2cfd5
913e23b
f08767c
b2af6e2
3e58646
aa0b9a7
905d31e
be1a18a
228ceac
6b939c5
2e1795b
0cd252e
607ec8f
e054219
e00119b
eb8e960
709cdd5
bd956bd
8db7a4c
8b2ff86
251865d
3be1447
271da9a
0d83fa9
b85f8b8
dfa6528
ed1a762
7ec406c
7780231
598fe13
20e8cdf
71f5453
318b79b
f4f6145
ac59d22
bd026d0
225a688
df40820
a1f8881
c32c44d
676ad40
b9f75b9
192451b
1f72890
78eead5
3784a9a
adf5d4c
b63c47e
ee81ed7
f681587
ce3d7c1
9800dca
7c4d0d7
22c605f
d15f4bf
f7b923f
4225145
482ca98
33e8f6a
c6df2b8
92e7542
ef4142e
a4f1934
dcd0b5e
c1dfbb1
6505614
f1a42ff
9a490d8
dd52fc7
92afe46
c3711ba
89b2b9c
69e4614
ad9a407
44fd17a
1f22eca
7251648
d119c11
e77d50a
7065662
615cb57
f21a517
c4c16f1
572d1b8
07bb3a1
6825ec0
63a8bcc
f2baad4
50b2a2e
955b6d3
5b8d48b
2634432
0e55af8
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,33 @@ | ||
import { styled } from 'styled-components'; | ||
|
||
const CollectingInformation = () => { | ||
return ( | ||
<Container> | ||
<RegisterTitle>나만의 파트 저장하기</RegisterTitle> | ||
<Warning>같은 파트에 대한 중복 등록은 한 번의 등록으로 처리됩니다.</Warning> | ||
</Container> | ||
); | ||
}; | ||
|
||
export default CollectingInformation; | ||
|
||
const Container = styled.div``; | ||
|
||
const RegisterTitle = styled.h2` | ||
font-size: 18px; | ||
font-weight: 700; | ||
color: ${({ theme: { color } }) => color.white}; | ||
|
||
@media (min-width: ${({ theme }) => theme.breakPoints.md}) { | ||
font-size: 22px; | ||
} | ||
`; | ||
|
||
const Warning = styled.div` | ||
font-size: 14px; | ||
color: ${({ theme: { color } }) => color.subText}; | ||
|
||
@media (min-width: ${({ theme }) => theme.breakPoints.md}) { | ||
font-size: 18px; | ||
} | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,44 @@ | ||
import { styled } from 'styled-components'; | ||
import styled from 'styled-components'; | ||
import { useAuthContext } from '@/features/auth/components/AuthProvider'; | ||
import useVoteInterfaceContext from '@/features/songs/hooks/useVoteInterfaceContext'; | ||
import VideoSlider from '@/features/youtube/components/VideoSlider'; | ||
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 useToastContext from '@/shared/components/Toast/hooks/useToastContext'; | ||
import { toPlayingTimeText } from '@/shared/utils/convertTime'; | ||
import copyClipboard from '@/shared/utils/copyClipBoard'; | ||
import { usePostKillingPart } from '../remotes/usePostKillingPart'; | ||
import KillingPartToggleGroup from './KillingPartToggleGroup'; | ||
|
||
const VoteInterface = () => { | ||
const { showToast } = useToastContext(); | ||
const { interval, partStartTime, songId, songVideoId } = useVoteInterfaceContext(); | ||
const { videoPlayer } = useVideoPlayerContext(); | ||
|
||
const { createKillingPart } = usePostKillingPart(); | ||
const RegisterPart = () => { | ||
const { isOpen, openModal, closeModal } = useModal(); | ||
|
||
const { showToast } = useToastContext(); | ||
const { user } = useAuthContext(); | ||
const { interval, partStartTime, songId, songVideoId } = useCollectingPartContext(); | ||
const video = useVideoPlayerContext(); | ||
const { createKillingPart } = usePostKillingPart(); | ||
|
||
const voteTimeText = toPlayingTimeText(partStartTime, partStartTime + interval); | ||
|
||
// 현재 useMutation 훅이 response 객체를 리턴하지 않고 내부적으로 처리합니다. | ||
// 때문에 컴포넌트 단에서 createKillingPart 성공 여부에 따라 등록 완료 만료를 처리를 할 수 없어요! | ||
// 현재 비로그인 시에 등록을 누르면 두 개의 모달이 뜹니다. | ||
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. 현재 존재하는 버그입니다. 커멘트보다는 주석으로 남겨놓는 게 좋을 것 같아서 주석처리했어요. |
||
const submitKillingPart = async () => { | ||
videoPlayer.current?.pauseVideo(); | ||
video.pause(); | ||
await createKillingPart(songId, { startSecond: partStartTime, length: interval }); | ||
openModal(); | ||
}; | ||
|
||
const voteTimeText = toPlayingTimeText(partStartTime, partStartTime + interval); | ||
|
||
const copyPartVideoUrl = async () => { | ||
await copyClipboard(`https://www.youtube.com/watch?v=${songVideoId}`); | ||
await copyClipboard(`https://www.youtube.com/watch?v=${songVideoId}&t=${partStartTime}s`); | ||
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. 굿 |
||
closeModal(); | ||
showToast('클립보드에 영상링크가 복사되었습니다.'); | ||
}; | ||
|
||
return ( | ||
<Container> | ||
<RegisterTitle>당신의 킬링파트를 등록하세요</RegisterTitle> | ||
<Spacing direction="vertical" size={4} /> | ||
<Warning>같은 파트에 대한 여러 번의 등록은 한 번의 등록으로 처리됩니다.</Warning> | ||
<Spacing direction="vertical" size={16} /> | ||
<KillingPartToggleGroup /> | ||
<Spacing direction="vertical" size={24} /> | ||
<VideoSlider /> | ||
<Spacing direction="vertical" size={16} /> | ||
<Register type="button" onClick={submitKillingPart}> | ||
<> | ||
<RegisterButton type="submit" onClick={submitKillingPart}> | ||
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.
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.
|
||
등록 | ||
</Register> | ||
|
||
</RegisterButton> | ||
<Modal isOpen={isOpen} closeModal={closeModal}> | ||
<ModalTitle> | ||
<TitleColumn>{user?.nickname}님의</TitleColumn> | ||
|
@@ -68,39 +57,34 @@ const VoteInterface = () => { | |
</Share> | ||
</ButtonContainer> | ||
</Modal> | ||
</Container> | ||
</> | ||
); | ||
}; | ||
|
||
export default VoteInterface; | ||
export default RegisterPart; | ||
|
||
const Container = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
`; | ||
const RegisterButton = styled.button` | ||
width: 100%; | ||
margin-top: auto; | ||
padding: 8px 11px; | ||
|
||
const RegisterTitle = styled.p` | ||
font-size: 22px; | ||
font-weight: 700; | ||
color: ${({ theme: { color } }) => color.white}; | ||
letter-spacing: 6px; | ||
|
||
@media (max-width: ${({ theme }) => theme.breakPoints.md}) { | ||
font-size: 18px; | ||
} | ||
`; | ||
|
||
const Register = styled.button` | ||
cursor: pointer; | ||
background-color: ${({ theme: { color } }) => color.primary}; | ||
border-radius: 6px; | ||
|
||
width: 100%; | ||
height: 36px; | ||
@media (min-width: ${({ theme }) => theme.breakPoints.md}) { | ||
position: static; | ||
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. |
||
left: unset; | ||
transform: unset; | ||
ukkodeveloper marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
font-weight: 700; | ||
color: ${({ theme: { color } }) => color.white}; | ||
width: 100%; | ||
padding: 11px 15px; | ||
|
||
background-color: ${({ theme: { color } }) => color.primary}; | ||
border: none; | ||
border-radius: 10px; | ||
font-size: 18px; | ||
} | ||
`; | ||
|
||
const ModalTitle = styled.h3``; | ||
|
@@ -121,13 +105,8 @@ const ModalContent = styled.div` | |
const Message = styled.div``; | ||
|
||
const Button = styled.button` | ||
cursor: pointer; | ||
|
||
height: 36px; | ||
|
||
color: ${({ theme: { color } }) => color.white}; | ||
|
||
border: none; | ||
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. 💬 global style로 들어간 부분을 빼주신건가용? |
||
border-radius: 10px; | ||
`; | ||
|
||
|
@@ -146,7 +125,3 @@ const ButtonContainer = styled.div` | |
gap: 16px; | ||
width: 100%; | ||
`; | ||
|
||
const Warning = styled.div` | ||
color: ${({ theme: { color } }) => color.subText}; | ||
`; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,39 @@ | ||||||||||||||||||||||||||||||||||||||
import React from 'react'; | ||||||||||||||||||||||||||||||||||||||
import styled from 'styled-components'; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
interface SoundWaveProps { | ||||||||||||||||||||||||||||||||||||||
length: number; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
const SoundWave = ({ length }: SoundWaveProps) => { | ||||||||||||||||||||||||||||||||||||||
return Array.from({ length }, (_, index) => { | ||||||||||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||||||||||
<React.Fragment key={index}> | ||||||||||||||||||||||||||||||||||||||
<LongBar /> | ||||||||||||||||||||||||||||||||||||||
<ShortBar /> | ||||||||||||||||||||||||||||||||||||||
</React.Fragment> | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||
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. 💬 개인적으로 컴포넌트에서 jsx를 반환하는 return 아래에서는 배열의 return이라던지,
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. return 사이에 로직이 추가되어서 return 키워드를 그대로 사용했습니다. 좋은 지적 감사합니다. |
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
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; | ||||||||||||||||||||||||||||||||||||||
`; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const ShortBar = styled.div` | ||||||||||||||||||||||||||||||||||||||
z-index: 2; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
width: 4px; | ||||||||||||||||||||||||||||||||||||||
height: 15px; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
background-color: ${({ theme: { color } }) => color.white}; | ||||||||||||||||||||||||||||||||||||||
border-radius: 5px; | ||||||||||||||||||||||||||||||||||||||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import styled from 'styled-components'; | ||
import playIcon from '@/assets/icon/fill-play.svg'; | ||
import pauseIcon from '@/assets/icon/pause.svg'; | ||
import useCollectingPartContext from '@/features/killingParts/hooks/useCollectingPartContext'; | ||
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, toggleEntirePlaying } = useCollectingPartContext(); | ||
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 = () => { | ||
video.pause(); | ||
}; | ||
|
||
return ( | ||
<Flex $gap={14} $justify="flex-end"> | ||
<Badge>{partStartTimeText}</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> | ||
); | ||
}; | ||
export default VideoBadges; | ||
|
||
const Badge = styled.span<{ $isActive?: boolean }>` | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
|
||
height: 30px; | ||
min-width: 40px; | ||
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. style lint가 적용 안되었네용 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. 적용 완료했습니다! |
||
padding: 0 10px; | ||
|
||
font-size: 13px; | ||
color: ${({ theme: { color }, $isActive }) => ($isActive ? color.black : color.white)}; | ||
text-align: center; | ||
|
||
background-color: ${({ theme: { color }, $isActive }) => | ||
$isActive ? color.magenta200 : color.disabled}; | ||
border-radius: 40px; | ||
|
||
transition: background-color 0.2s ease-in; | ||
|
||
@media (min-width: ${({ theme }) => theme.breakPoints.md}) { | ||
font-size: 14px; | ||
} | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import VideoBadges from '@/features/killingParts/components/VideoBadges'; | ||
import VideoIntervalStepper from '@/features/killingParts/components/VideoIntervalStepper'; | ||
import WaveScrubber from '@/features/killingParts/components/WaveScrubber'; | ||
import Flex from '@/shared/components/Flex/Flex'; | ||
|
||
const VideoController = () => { | ||
return ( | ||
<Flex $gap={8} $direction={'column'}> | ||
<VideoIntervalStepper /> | ||
<VideoBadges /> | ||
<WaveScrubber /> | ||
</Flex> | ||
); | ||
}; | ||
|
||
export default VideoController; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { css, styled } from 'styled-components'; | ||
import useCollectingPartContext from '@/features/killingParts/hooks/useCollectingPartContext'; | ||
import Flex from '@/shared/components/Flex/Flex'; | ||
|
||
const VideoIntervalStepper = () => { | ||
const { interval, increasePartInterval, decreasePartInterval } = useCollectingPartContext(); | ||
|
||
return ( | ||
<Flex $gap={20}> | ||
<ControlButton onClick={decreasePartInterval}>-</ControlButton> | ||
<CountText>{`${interval} 초`}</CountText> | ||
<ControlButton onClick={increasePartInterval}>+</ControlButton> | ||
</Flex> | ||
); | ||
}; | ||
|
||
export default VideoIntervalStepper; | ||
|
||
const StepperElementStyle = css` | ||
flex: 1; | ||
|
||
min-width: 50px; | ||
margin: 0; | ||
padding: 4px 11px; | ||
|
||
font-weight: 700; | ||
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. 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. 일단 weight 뺐습니다. 나중에 추가해보죵 |
||
line-height: 1.8; | ||
text-align: center; | ||
|
||
border: none; | ||
border-radius: 10px; | ||
`; | ||
|
||
const ControlButton = styled.button` | ||
${StepperElementStyle}; | ||
color: ${({ theme: { color } }) => color.white}; | ||
background-color: ${({ theme: { color } }) => color.secondary}; | ||
|
||
&:active { | ||
background-color: ${({ theme: { color } }) => color.disabled}; | ||
transition: box-shadow 0.2s ease; | ||
} | ||
`; | ||
|
||
const CountText = styled.p` | ||
${StepperElementStyle}; | ||
color: ${({ theme: { color } }) => color.black}; | ||
background-color: ${({ theme: { color } }) => color.white}; | ||
|
||
&:active { | ||
box-shadow: 0 0 0 1px inset ${({ theme: { color } }) => color.magenta300}; | ||
transition: box-shadow 0.1s ease; | ||
} | ||
`; |
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.
💬 이거 피시에서 한줄로 가능할까요?
해당 부분 반응형 폰트 사이즈 제거하고, 컨테이너 320px -> 326px 하니깐 들어갔어요