import React, { Fragment, useState } from 'react'; import PropTypes from 'prop-types'; import Sound from 'react-sound'; import { sprintf } from 'sprintf-js'; import classNames from 'classnames'; import soundProvider from './soundProvider'; import Cover from './components/Cover'; import Button from './components/Button'; import ProgressBar from './components/ProgressBar'; import Time from './components/Time'; import VolumeControl from './components/VolumeControl'; import TracklistWrap from './components/TracklistWrap'; import { PlayIcon, PauseIcon, NextIcon, PreviousIcon, PlaylistIcon, RefreshIcon, LyricsIcon, } from './components/Icons'; import { AppContext } from '../App'; import typographyDisabled from '../utils/typography-disabled'; import PlayerButtons from './components/PlayerButtons'; const propTypes = { tracks: PropTypes.arrayOf(PropTypes.object), playStatus: PropTypes.oneOf([ Sound.status.PLAYING, Sound.status.PAUSED, Sound.status.STOPPED, ]), activeIndex: PropTypes.number, volume: PropTypes.number, position: PropTypes.number, duration: PropTypes.number, currentTrack: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types playTrack: PropTypes.func.isRequired, togglePlay: PropTypes.func.isRequired, nextTrack: PropTypes.func.isRequired, prevTrack: PropTypes.func.isRequired, setPosition: PropTypes.func.isRequired, setVolume: PropTypes.func.isRequired, toggleTracklistCycling: PropTypes.func.isRequired, cycleTracks: PropTypes.bool.isRequired, allowTracklistToggle: PropTypes.bool, allowTracklistLoop: PropTypes.bool, reverseTrackOrder: PropTypes.bool, displayTrackNo: PropTypes.bool, displayTracklist: PropTypes.bool, displayActiveCover: PropTypes.bool, displayTracklistCovers: PropTypes.bool, limitTracklistHeight: PropTypes.bool, tracklistHeight: PropTypes.number, displayBuyButtons: PropTypes.bool, buyButtonsTarget: PropTypes.bool, displayArtistNames: PropTypes.bool, setTrackCycling: PropTypes.func.isRequired, repeatingTrackIndex: PropTypes.number, allowTrackLoop: PropTypes.bool, playbackRate: PropTypes.number, setPlaybackRate: PropTypes.func, skipAmount: PropTypes.number, skipPosition: PropTypes.func.isRequired, countdownTimerByDefault: PropTypes.bool, allowPlaybackRate: PropTypes.bool, buffering: PropTypes.bool, playerButtons: PropTypes.arrayOf( PropTypes.shape({ title: PropTypes.string, url: PropTypes.string, icon: PropTypes.string, }).isRequired, ), playerId: PropTypes.string, }; const GlobalFooterPlayer = ({ tracks, playStatus, activeIndex, volume, position, duration, playbackRate, playerId, currentTrack, playTrack, togglePlay, nextTrack, prevTrack, setPosition, setVolume, toggleTracklistCycling, cycleTracks, setTrackCycling, setPlaybackRate, allowPlaybackRate, allowTracklistToggle, allowTracklistLoop, allowTrackLoop, reverseTrackOrder, displayTracklist, displayTrackNo, displayTracklistCovers, displayActiveCover, limitTracklistHeight, tracklistHeight, displayBuyButtons, buyButtonsTarget, displayArtistNames, repeatingTrackIndex, skipAmount, skipPosition, countdownTimerByDefault, buffering, playerButtons, }) => { const [isTrackListOpen, setTracklistOpen] = useState(displayTracklist); const toggleTracklist = () => { setTracklistOpen(x => !x); }; const classes = classNames({ 'ai-wrap': true, 'ai-type-global-footer': true, 'ai-is-loading': !tracks.length, 'ai-with-typography': !typographyDisabled(), }); const audioControlClasses = classNames({ 'ai-audio-control': true, 'ai-audio-playing': playStatus === Sound.status.PLAYING, 'ai-audio-loading': buffering, }); return (
{displayActiveCover && ( )}
{tracks.length > 1 && ( )} {tracks.length > 1 && ( )} {allowTracklistLoop && ( )} {allowPlaybackRate && ( )} {skipAmount > 0 && ( )} {currentTrack && currentTrack.lyrics && !isTrackListOpen && ( {({ toggleLyricsModal }) => ( )} )}

{currentTrack.title}

{(tracks.length === 0 || currentTrack.subtitle) && displayArtistNames && (

{currentTrack.subtitle}

)}
{playerButtons?.length > 0 && }
); }; GlobalFooterPlayer.propTypes = propTypes; export default soundProvider(GlobalFooterPlayer, { onFinishedPlaying(props) { const { repeatingTrackIndex, cycleTracks, nextTrack, activeIndex, playTrack, trackQueue, } = props; if (repeatingTrackIndex != null) { playTrack(repeatingTrackIndex); return; } if (cycleTracks) { nextTrack(); return; } // Check if not the last track if (activeIndex !== trackQueue[trackQueue.length - 1]) { nextTrack(); } }, });