style: implement basic media player styles

This commit is contained in:
jinhojang6 2023-08-09 00:43:45 +09:00
parent 1481dd0e7a
commit c29087be8f
4 changed files with 82 additions and 14 deletions

View File

@ -13,7 +13,6 @@ import { HeadingElementsRef } from '@/utils/ui.utils'
import UnbodyDocumentTypeNames = UnbodyGraphQl.UnbodyDocumentTypeNames
import { ArticleHeading } from '@/components/Article/Article.Heading'
import ReactPlayer from 'react-player'
import { GlobalAudioPlayer } from '../GlobalAudioPlayer'
export const RenderArticleBlock = ({
block,
@ -53,6 +52,7 @@ export const RenderArticleBlock = ({
const isYoutubeRegex =
/https?:\/\/(?:www\.)?youtu\.be\/([a-zA-Z0-9_-]{11})/
const isYoutube = isYoutubeRegex.test(block.text)
const youtubeLink = block.text.match(isYoutubeRegex) ?? []

View File

@ -0,0 +1,20 @@
.audioPlayer > input[type='range'] {
width: 100%;
accent-color: black;
}
.audioPlayer > input[type='range']:focus {
outline: none;
}
.audioPlayer > input[type='range']::-webkit-slider-runnable-track {
width: 100%;
height: 8px;
cursor: grabbing;
}
.audioPlayer > input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
margin-top: -4px;
}

View File

@ -4,11 +4,15 @@ import { useRef, useState } from 'react'
import { PlayIcon } from '../Icons/PlayIcon'
import { PauseIcon } from '../Icons/PauseIcon'
import { VolumeIcon } from '../Icons/VolumeIcon'
import styles from './GlobalAudioPlayer.module.css'
import { convertSecToMinAndSec } from '@/utils/string.utils'
import { Typography } from '@acid-info/lsd-react'
type StateProps = {
url: string | null
pip: boolean
playing: boolean
playedSeconds: number
controls: boolean
light: boolean
volume: number
@ -30,6 +34,7 @@ export default function GlobalAudioPlayer() {
url: TEMP_URL,
pip: false,
playing: false,
playedSeconds: 0,
controls: false,
light: false,
volume: 0.8,
@ -107,19 +112,29 @@ export default function GlobalAudioPlayer() {
setState((prev) => ({ ...prev, playbackRate: parseFloat(e.target.value) }))
}
// const handleProgress = (newState: StateProps) => {
// if (!state.seeking) {
// setState((prev) => ({ ...prev, ...newState }))
// }
// }
const handleProgress = (newState: { playedSeconds: number }) => {
setState((prev) => ({ ...prev, playedSeconds: newState.playedSeconds }))
}
return (
<Container>
<AudioPlayer>
<Buttons>
<PlayPause onClick={handlePlayPause}>
{state.playing ? <PauseIcon /> : <PlayIcon />}
</PlayPause>
<Row>
<PlayPause onClick={handlePlayPause}>
{state.playing ? <PauseIcon /> : <PlayIcon />}
</PlayPause>
<TimeContainer>
<Time variant="body3">
{convertSecToMinAndSec(state.playedSeconds)}
</Time>
<Typography variant="body3">/</Typography>
<Time variant="body3">
{convertSecToMinAndSec(state.duration)}
</Time>
</TimeContainer>
</Row>
<VolumeContainer onClick={() => setShowVolume((prev) => !prev)}>
{showVolume && (
<VolumeGauge>
@ -139,9 +154,8 @@ export default function GlobalAudioPlayer() {
{/* <button onClick={handleStop}>Stop</button> */}
<Seek>
<Seek className={styles.audioPlayer}>
<input
className="audio-player"
type="range"
min={0}
max={0.999999}
@ -156,6 +170,7 @@ export default function GlobalAudioPlayer() {
<ReactPlayer
ref={ref}
style={{ display: 'none' }}
url={state.url ?? TEMP_URL}
width="100%"
height="100%"
@ -177,8 +192,9 @@ export default function GlobalAudioPlayer() {
onEnded={handleEnded}
onError={(e) => console.log('onError', e)}
onDuration={handleDuration}
// onProgress={handleProgress}
onProgress={handleProgress}
/>
<RightMenu></RightMenu>
</Container>
)
}
@ -195,6 +211,7 @@ const Container = styled.div`
bottom: 0;
left: 0;
border-top: 1px solid rgb(var(--lsd-border-primary));
box-sizing: border-box;
`
const Buttons = styled.div`
@ -224,8 +241,12 @@ const VolumeGauge = styled.div`
const AudioPlayer = styled.div`
display: flex;
flex-direction: column;
gap: 16px;
width: 100%;
gap: 8px;
width: 60%;
`
const RightMenu = styled.div`
width: 40%;
`
const PlayPause = styled.button`
@ -234,4 +255,19 @@ const PlayPause = styled.button`
justify-content: center;
border: none;
background: none;
margin-right: 8px;
`
const Row = styled.div`
display: flex;
align-items: center;
white-space: pre-wrap;
`
const TimeContainer = styled(Row)`
gap: 8px;
`
const Time = styled(Typography)`
width: 32px;
`

View File

@ -41,3 +41,15 @@ export const calcReadingTime = (text: string): number => {
const numberOfWords = text.split(/\s/g).length
return Math.ceil(numberOfWords / wordsPerMinute)
}
export function convertSecToMinAndSec(totalSeconds: number) {
// Convert seconds to minutes and seconds
const minutes = Math.floor(totalSeconds / 60)
const seconds = Math.floor(totalSeconds % 60)
// Ensure two digit format
const formattedMinutes = String(minutes).padStart(2, '0')
const formattedSeconds = String(seconds).padStart(2, '0')
return `${formattedMinutes}:${formattedSeconds}`
}