Files
q-blog/src/components/common/AudioPlayer.tsx
2023-12-08 13:56:56 -05:00

193 lines
4.6 KiB
TypeScript

import React, { useEffect, useMemo, useRef, useState } from 'react'
import { Box, IconButton, Slider } from '@mui/material'
import { CircularProgress, Typography } from '@mui/material'
import AudioPlyr from 'philliplm-react-modern-audio-player'
import LinearProgress from '@mui/material/LinearProgress'
import {
PlayArrow,
Pause,
VolumeUp,
Fullscreen,
PictureInPicture
} from '@mui/icons-material'
import { styled } from '@mui/system'
import {
removeAudio,
setShowingAudioPlayer
} from '../../state/features/globalSlice'
import { useDispatch, useSelector } from 'react-redux'
import { RootState } from '../../state/store'
const VideoContainer = styled(Box)`
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
margin: 20px 0px;
z-index: 501;
`
const VideoElement = styled('video')`
width: 100%;
height: auto;
background: rgb(33, 33, 33);
`
const ControlsContainer = styled(Box)`
position: absolute;
display: flex;
align-items: center;
justify-content: space-between;
bottom: 0;
left: 0;
right: 0;
padding: 8px;
background-color: rgba(0, 0, 0, 0.6);
`
interface VideoPlayerProps {
src?: string
poster?: string
name?: string
identifier?: string
service?: string
autoplay?: boolean
title?: string
description?: string
playlist?: IPlaylist[]
currAudio: number | null
}
export interface IPlaylist {
name: string
identifier: string
service: string
title: string
description: string
}
interface CustomWindow extends Window {
_qdnTheme: any // Replace 'any' with the appropriate type if you know it
}
const customWindow = window as unknown as CustomWindow
const themeColor = customWindow?._qdnTheme
export const AudioPlayer: React.FC<VideoPlayerProps> = ({ currAudio }) => {
const [isLoading, setIsLoading] = useState<boolean>(false)
const { downloads, showingAudioPlayer } = useSelector(
(state: RootState) => state.global
)
const dispatch = useDispatch()
const downloadsLength: number = useMemo(
() =>
Object.keys(downloads)
.map((item) => {
return downloads[item]
})
.filter(
(download: any) =>
download?.service === 'AUDIO' &&
download?.status?.status === 'READY' &&
!!download.url
).length,
[downloads]
)
const audioPlayList = useMemo(() => {
const filterAudios = Object.keys(downloads)
.map((item) => {
return downloads[item]
})
.filter(
(download: any) =>
download?.service === 'AUDIO' &&
download?.url &&
download?.status?.status === 'READY'
)
return filterAudios.map((audio: any, index: number) => {
return {
name: audio?.blogPost?.audioTitle,
src: audio?.url,
id: index + 1,
identifier: audio?.identifier,
description: audio?.blogPost?.audioDescription || ''
}
})
}, [downloadsLength])
const currAudioMemo: number | null = useMemo(() => {
const findIndex = audioPlayList.findIndex(
(item) => item?.identifier === currAudio
)
if (findIndex !== -1) {
return findIndex
}
return null
}, [audioPlayList, currAudio])
if (isLoading)
return (
<Box
sx={{
isolation: 'isolate',
width: '100%',
position: 'fixed',
colorScheme: 'light',
bottom: '0px',
padding: '10px',
height: '50px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'flex-start'
}}
>
<Typography
sx={{
fontSize: '10px'
}}
>
Loading playlist...
</Typography>
<LinearProgress
sx={{
width: '100%'
}}
/>
</Box>
)
if (audioPlayList.length === 0 || !showingAudioPlayer) return null
return (
<VideoContainer>
<AudioPlyr
rootContainerProps={{
defaultColorScheme: themeColor === 'dark' ? 'dark' : 'light',
colorScheme: themeColor === 'dark' ? 'dark' : 'light'
}}
currentIndex={currAudioMemo}
playList={audioPlayList}
activeUI={{
all: true
}}
placement={{
player: 'bottom',
playList: 'top',
volumeSlider: 'top'
}}
closeCallback={() => {
dispatch(setShowingAudioPlayer(false))
}}
// rootContainerProps={{
// colorScheme: theme,
// width
// }}
/>
</VideoContainer>
)
}