import { SyntheticEvent, useEffect, useRef, useState } from 'react'; import { MdFastForward, MdFastRewind, MdGraphicEq, MdLooksOne, MdNavigateBefore, MdNavigateNext, MdPause, MdPlayArrow, MdRepeat, MdRepeatOne, MdStop, MdTrendingFlat, } from 'react-icons/md'; import { useActivePlaylistService } from '@/service/ActivePlaylist'; import { useSpecificAlbum } from '@/service/Album'; import { useSpecificArtists } from '@/service/Artist'; import { useSpecificGender } from '@/service/Gender'; import { useSpecificTrack } from '@/service/Track'; import { DataUrlAccess } from '@/utils/data-url-access'; import { useColorThemeValue } from '@/theme/ThemeContext'; import { isNullOrUndefined } from '@/utils/validator'; import { Icon } from './Icon'; import { Flex, Text } from '@/ui'; export enum PlayMode { PLAY_ONE, PLAY_ALL, PLAY_ONE_LOOP, PLAY_ALL_LOOP, } const playModeIcon = { [PlayMode.PLAY_ONE]: , [PlayMode.PLAY_ALL]: , [PlayMode.PLAY_ONE_LOOP]: , [PlayMode.PLAY_ALL_LOOP]: , }; export type AudioPlayerProps = {}; const formatTime = (time) => { if (time && !isNaN(time)) { const minutes = Math.floor(time / 60); const formatMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`; const seconds = Math.floor(time % 60); const formatSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`; return `${formatMinutes}:${formatSeconds}`; } return '00:00'; }; export const AudioPlayer = ({ }: AudioPlayerProps) => { const { playTrackList, trackOffset, previous, next, first } = useActivePlaylistService(); const audioRef = useRef(null); const [isPlaying, setIsPlaying] = useState(false); const [timeProgress, setTimeProgress] = useState(0); const [playingMode, setPlayingMode] = useState(PlayMode.PLAY_ALL); const [duration, setDuration] = useState(0); const { dataTrack } = useSpecificTrack( trackOffset !== undefined ? playTrackList[trackOffset] : undefined ); const { dataAlbum } = useSpecificAlbum(dataTrack?.albumId); const { dataGender } = useSpecificGender(dataTrack?.genderId); const { dataArtists } = useSpecificArtists(dataTrack?.artists); const [mediaSource, setMediaSource] = useState(''); useEffect(() => { setMediaSource( dataTrack && dataTrack?.dataId ? DataUrlAccess.getUrl(dataTrack?.dataId) : '' ); }, [dataTrack, setMediaSource]); const backColor = useColorThemeValue('back.100', 'back.800'); const configButton = { borderRadius: 'full', background: '#00000000', _hover: { boxShadow: 'outline-over', bgColor: 'brand.500', }, width: "50px", height: "50px", padding: "5px", }; useEffect(() => { if (!audioRef || !audioRef.current) { return; } if (isPlaying) { audioRef.current.play(); } else { audioRef.current.pause(); } }, [isPlaying, audioRef]); const onAudioEnded = () => { if (playTrackList.length === 0 || isNullOrUndefined(trackOffset)) { return; } if (playingMode === PlayMode.PLAY_ALL_LOOP) { if (playTrackList.length == trackOffset + 1) { first(); } else { next(); } } else if (playingMode === PlayMode.PLAY_ALL) { next(); } else if (playingMode === PlayMode.PLAY_ONE_LOOP) { onSeek(0); onPlay(); } }; const onSeek = (newValue) => { console.log(`onSeek: ${newValue}`); if (!audioRef || !audioRef.current) { return; } audioRef.current.currentTime = newValue; }; const onPlay = () => { if (!audioRef || !audioRef.current) { return; } if (isPlaying) { audioRef.current.pause(); } else { audioRef.current.play(); } }; const onStop = () => { if (!audioRef || !audioRef.current) { return; } if (audioRef.current.currentTime == 0 && audioRef.current.paused) { // TODO remove curent playing value } else { audioRef.current.pause(); audioRef.current.currentTime = 0; } }; const onNavigatePrevious = () => { previous(); }; const onFastRewind = () => { if (!audioRef || !audioRef.current) { return; } audioRef.current.currentTime -= 10; }; const onFastForward = () => { if (!audioRef || !audioRef.current) { return; } audioRef.current.currentTime += 10; }; const onNavigateNext = () => { next(); }; const onTypePlay = () => { setPlayingMode((value: PlayMode) => { if (value === PlayMode.PLAY_ONE) { return PlayMode.PLAY_ALL; } else if (value === PlayMode.PLAY_ALL) { return PlayMode.PLAY_ONE_LOOP; } else if (value === PlayMode.PLAY_ONE_LOOP) { return PlayMode.PLAY_ALL_LOOP; } else { return PlayMode.PLAY_ONE; } }); }; /** * Call when meta-data is updated */ function onChangeMetadata(): void { const seconds = audioRef.current?.duration; if (seconds !== undefined) { setDuration(seconds); } } const onTimeUpdate = () => { if (!audioRef || !audioRef.current) { return; } console.log(`onTimeUpdate ${audioRef.current.currentTime}`); setTimeProgress(audioRef.current.currentTime); }; const onDurationChange = (event) => { }; const onChangeStateToPlay = () => { setIsPlaying(true); }; const onChangeStateToPause = () => { setIsPlaying(false); }; return ( <> {!isNullOrUndefined(trackOffset) && ( {dataTrack?.name ?? '???'} {dataArtists.map((data) => data.name).join(', ')} /{' '} {dataAlbum && dataAlbum?.name} {dataGender && ` / ${dataGender.name}`} <>TODO ... {/* {/ * * /} */} {formatTime(timeProgress)} {formatTime(duration)} {/* {isPlaying ? ( ) : ( )} {playModeIcon[playingMode]} */} )}