Skip to content
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

[Graph mindset] Add mute and playback speed button #2576

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/components/mindset/components/MediaPlayer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const MediaPlayerComponent = ({ mediaUrl }: Props) => {
setIsSeeking,
setPlayerRef,
playerRef,
playbackSpeed,
} = usePlayerStore((s) => s)

useEffect(() => () => resetPlayer(), [resetPlayer])
Expand Down Expand Up @@ -184,6 +185,7 @@ const MediaPlayerComponent = ({ mediaUrl }: Props) => {
onPlay={handlePlay}
onProgress={handleProgress}
onReady={handleReady}
playbackRate={playbackSpeed}
playing={isPlaying}
url={mediaUrl || ''}
volume={volume}
Expand Down
69 changes: 67 additions & 2 deletions src/components/mindset/components/PlayerContols/Controls/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import { IconButton } from '@mui/material'
import { memo } from 'react'
import { memo, useState } from 'react'
import styled from 'styled-components'
import PauseIcon from '~/components/Icons/PauseIcon'
import PlayIcon from '~/components/Icons/PlayIcon'
import { Flex } from '~/components/common/Flex'
import { usePlayerStore } from '~/stores/usePlayerStore'
import { colors } from '~/utils/colors'
import VolumeIcon from '~/components/Icons/VolumeIcon'
import MuteVolumeIcon from '~/components/Icons/MuteVolumeIcon'

export const Controls = memo(() => {
const isPlaying = usePlayerStore((s) => s.isPlaying)
const setIsPlaying = usePlayerStore((s) => s.setIsPlaying)
const setVolume = usePlayerStore((s) => s.setVolume)
const setPlaybackSpeed = usePlayerStore((s) => s.setPlaybackSpeed)
const playbackSpeed = usePlayerStore((s) => s.playbackSpeed)
const playerRef = usePlayerStore((s) => s.playerRef)
const [isMuted, setIsMuted] = useState(false)
const speedOptions = [0.5, 1, 1.5, 2]

const handleRewind = () => {
if (playerRef) {
Expand All @@ -32,8 +39,30 @@ export const Controls = memo(() => {
setIsPlaying(!isPlaying)
}

const toggleMute = () => {
setIsMuted(!isMuted)
setVolume(isMuted ? 1 : 0)
}

const cycleSpeed = () => {
const currentIndex = speedOptions.indexOf(playbackSpeed)
const nextIndex = (currentIndex + 1) % speedOptions.length
const newSpeed = speedOptions[nextIndex]

setPlaybackSpeed(newSpeed)

if (playerRef) {
const internalPlayer = playerRef.getInternalPlayer() as HTMLMediaElement

if (internalPlayer && typeof internalPlayer.playbackRate !== 'undefined') {
internalPlayer.playbackRate = newSpeed
}
}
}

return (
<Wrapper>
<MuteWrapper onClick={toggleMute}>{isMuted ? <MuteVolumeIcon /> : <VolumeIcon />}</MuteWrapper>
<RewindIconWrapper onClick={handleRewind}>
<img alt="" src="RewindIcon.svg" />
</RewindIconWrapper>
Expand All @@ -43,6 +72,7 @@ export const Controls = memo(() => {
<ForwardIconWrapper onClick={handleFastForward}>
<img alt="" src="ForwardIcon.svg" />
</ForwardIconWrapper>
<SpeedButton onClick={cycleSpeed}>{playbackSpeed}x</SpeedButton>
</Wrapper>
)
})
Expand All @@ -54,7 +84,7 @@ const Wrapper = styled(Flex).attrs({
align: 'center',
justify: 'flex-start',
})`
width: 142px;
width: 200px;
height: 54px;
background: ${colors.BG1};
border-radius: 40px;
Expand Down Expand Up @@ -96,3 +126,38 @@ const ForwardIconWrapper = styled.div`
height: auto;
}
`

const MuteWrapper = styled.div`
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
cursor: pointer;
border-radius: 50%;
transition: background-color 0.3s ease;
color: ${colors.GRAY6};
svg {
margin-top: 3px;
width: 24px;
height: 24px;
}
&:hover {
background-color: ${colors.DROPDOWN_BG};
}
`

const SpeedButton = styled.button`
margin-top: 4px;
background: ${colors.BG1};
color: ${colors.GRAY6};
border: none;
width: 8px;
border-radius: 20px;
padding: 8px 20px 8px 8px;
font-size: 14px;
cursor: pointer;
transition: background-color 0.3s ease;
`
5 changes: 5 additions & 0 deletions src/stores/usePlayerStore/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type PlayerStore = {
playingTime: number
duration: number
volume: number
playbackSpeed: number
playingNode: NodeExtended | null
playerRef: ReactPlayer | null
setPlayingTime: (time: number) => void
Expand All @@ -24,6 +25,7 @@ type PlayerStore = {
setPlayingNodeLink: (link: string) => void
setIsSeeking: (isSeeking: boolean) => void
setPlayerRef: (playerRef: ReactPlayer) => void
setPlaybackSpeed: (speed: number) => void
}

const defaultData: Omit<
Expand All @@ -39,6 +41,7 @@ const defaultData: Omit<
| 'setPlayingNodeLink'
| 'setIsSeeking'
| 'setPlayerRef'
| 'setPlaybackSpeed'
> = {
isPlaying: false,
miniPlayerIsVisible: false,
Expand All @@ -48,6 +51,7 @@ const defaultData: Omit<
playingNode: null,
duration: 0,
volume: 0.5,
playbackSpeed: 1,
playerRef: null,
}

Expand Down Expand Up @@ -95,5 +99,6 @@ export const usePlayerStore = create<PlayerStore>()(
}
},
resetPlayer: () => set({ duration: defaultData.duration, hasError: defaultData.hasError }),
setPlaybackSpeed: (speed) => set({ playbackSpeed: speed }),
})),
)
Loading