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]}
*/}
)}
>
);
};