File indexing completed on 2025-05-04 05:31:15

0001 import React, { useState, useEffect, useRef} from "react";
0002 import Slider from 'rc-slider'; 
0003 import { Scrollbars } from 'react-custom-scrollbars';
0004 
0005 function MusicPlayerWrapper(props){
0006 
0007   return (
0008     <div>
0009       <MusicPlayer 
0010         product={props.product}
0011         items={props.slide.items} 
0012         containerWidth={props.width}
0013       />
0014     </div>
0015   )
0016 }
0017 
0018 function MusicPlayer(props){
0019 
0020   /* COMPONENT */
0021 
0022   const [ playIndex, setPlayIndex ] = useState(0);
0023   const prevIndex = usePrevious(playIndex);
0024   const [ isPlaying, setIsPlaying ] = useState();
0025   const [ isPaused, setIsPaused ] = useState();
0026   const [ audioVolume, setAudioVolume ] = useState(0.5);
0027   const [ isMuted, setIsMuted ] = useState(false);
0028   const [ currentTrackTime, setCurrentTrackTime ] = useState(0);
0029   const [ currentTrackTimeSeconds, setCurrentTrackTimeSeconds ] = useState(0);
0030   const [ currentTrackDuration, setcurrentTrackDuration ] = useState(0);
0031   const [ currentTrackProgress, setCurrentTrackProgress ] = useState(0);
0032   const [ theme, setTheme ] = useState('dark');
0033   let initialPLayedAudioArray = []
0034   props.items.forEach(function(i,index){
0035     let pl = 0;
0036     if (index === 0) pl = -1;
0037     const pa = {
0038       ...i,
0039       played:0,
0040       stopped:0
0041     }
0042     initialPLayedAudioArray.push(pa);
0043   })
0044   const [ playedAudioArray, setPlayedAudioArray ] = useState(initialPLayedAudioArray);
0045   const [ randomSupporter, setRandomSupporter ] = useState();
0046 
0047   const initialIsMobileValue = props.containerWidth < 600 ? true : false;
0048   const [ isMobile, setIsMobile ] = useState(initialIsMobileValue);
0049   const initialShowPlaylistValue = isMobile === true ? false : true;
0050   const [ showPlaylist, setShowPlaylist ] = useState(initialShowPlaylistValue);
0051 
0052   useEffect(() => {
0053     getRandomMusicsupporter();
0054   },[])
0055 
0056   useEffect(() => {
0057     const playerElement = document.getElementById("music-player-container").getElementsByTagName('audio');
0058     playerElement[0].volume = audioVolume;
0059   },[audioVolume])
0060 
0061   useEffect(() => {
0062     if (isPlaying) onPlayClick(true);
0063     if (isPaused){
0064         if (prevIndex === playIndex) onPlayClick();
0065         else  onPlayClick(true);
0066     }
0067     if (isPlaying === true) onReportAudioStop(props.items[prevIndex].musicSrc,playIndex)
0068   },[playIndex])
0069 
0070   // audio player
0071 
0072   function onPlayClick(reload,newPlayIndex){
0073 
0074     const playerElement = document.getElementById("music-player-container").getElementsByTagName('audio');
0075     let pi = newPlayIndex ? newPlayIndex : playIndex;
0076     const currentSrc = props.items[pi].musicSrc;
0077     
0078     if (isPaused === false ||  playerElement[0].currentTime && playerElement[0].currentTime === 0 || reload === true){
0079       playerElement[0].src = currentSrc;
0080       setCurrentTrackProgress(0);
0081     }
0082     playerElement[0].play();
0083     setIsPlaying(true);
0084     setIsPaused(false);
0085     onReportAudioPlay(currentSrc,newPlayIndex);
0086   }
0087 
0088   function onPauseClick(){
0089     const playerElement = document.getElementById("music-player-container").getElementsByTagName('audio');
0090     playerElement[0].pause();
0091     setIsPlaying(false);
0092     setIsPaused(true);
0093     onReportAudioStop(props.items[playIndex].musicSrc)
0094   }
0095 
0096   function onPrevTrackPlayClick(){
0097       let prevTrackIndex;
0098       if (playIndex === 0){
0099           prevTrackIndex = props.items.length - 1;
0100       } else {
0101           prevTrackIndex = playIndex - 1;
0102       }
0103       setPlayIndex(prevTrackIndex);
0104   }
0105 
0106   function onNextTrackPlayClick(){
0107       let nextTrackIndex;
0108       if (playIndex + 1 === props.items.length){
0109           nextTrackIndex = 0;
0110       } else {
0111           nextTrackIndex = playIndex + 1;
0112       }
0113       setPlayIndex(nextTrackIndex);
0114   }
0115  
0116   function onReportAudioPlay(musicSrc,newPlayIndex){  
0117     const audioItem = playedAudioArray.find((i => i.musicSrc === musicSrc));
0118     const audioItemIndex = newPlayIndex ? newPlayIndex : playedAudioArray.findIndex((i => i.musicSrc === musicSrc));
0119     const newAudioItem = {
0120       ...audioItem,
0121       played:audioItem.played + 1
0122     }
0123     const newPLayedAudioArray = [
0124       ...playedAudioArray.slice(0,audioItemIndex),
0125       newAudioItem,
0126       ...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)
0127     ];
0128 
0129     /*console.log('played audio array - ');
0130     console.log(playedAudioArray);
0131     console.log('audio item index - ' + audioItemIndex);
0132     console.log('audio item - ')
0133     console.log(audioItem);
0134     console.log( playedAudioArray[audioItemIndex]);
0135     console.log('is played - ' + playedAudioArray[audioItemIndex].played)*/
0136 
0137     if (playedAudioArray[audioItemIndex].played === 0){
0138 
0139       const audioStartUrl = "https://" + window.location.hostname + "/p/" + props.product.project_id + '/startmediaviewajax?collection_id='+audioItem.collection_id+'&file_id='+audioItem.file_id+'&type_id=2';
0140       //console.log('audio start url - ' + audioStartUrl);
0141       $.ajax({url: audioStartUrl}).done(function(res) { 
0142         //console.log('ajax res - ');
0143         //console.log(res);
0144         const newAudioItem = {
0145           ...audioItem,
0146           mediaViewId:res.MediaViewId,
0147           played:audioItem.played + 1
0148         }
0149         const newPLayedAudioArray = [
0150           ...playedAudioArray.slice(0,audioItemIndex),
0151           newAudioItem,
0152           ...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)
0153         ];
0154         setPlayedAudioArray(newPLayedAudioArray);
0155       });
0156     } else {
0157       setPlayedAudioArray(newPLayedAudioArray);
0158     }
0159   }
0160 
0161   function onReportAudioStop(musicSrc){
0162 
0163     const audioItem = playedAudioArray.find((i => i.musicSrc === musicSrc));
0164     const audioItemIndex = playedAudioArray.findIndex((i => i.musicSrc === musicSrc));
0165     const newAudioItem = {
0166       ...audioItem,
0167       stopped:audioItem.stopped + 1
0168     }
0169     const newPLayedAudioArray = [
0170       ...playedAudioArray.slice(0,audioItemIndex),
0171       newAudioItem,
0172       ...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)
0173     ];
0174 
0175     if  (playedAudioArray[audioItemIndex].stopped === 0){
0176 
0177       const audioStopUrl =   "https://" + window.location.hostname + "/p/" + props.product.project_id + "/stopmediaviewajax?media_view_id=" + playedAudioArray[audioItemIndex].mediaViewId;
0178 
0179       //console.log(audioStopUrl);
0180 
0181       $.ajax({url: audioStopUrl}).done(function(res) { 
0182         //console.log(res);
0183         setPlayedAudioArray(newPLayedAudioArray);
0184       });
0185     } else {
0186       setPlayedAudioArray(newPLayedAudioArray);
0187     }
0188   }
0189 
0190   function onUpdateCurrentTrackProgress(newTrackProgress){
0191     console.log(newTrackProgress);
0192     setCurrentTrackProgress(newTrackProgress);
0193     const newCurrentTrackTime = (currentTrackTimeSeconds / 100) * newTrackProgress;
0194     const playerElement = document.getElementById("music-player-container").getElementsByTagName('audio');
0195     playerElement[0].currentTime = newCurrentTrackTime;
0196     // playerElement[0].ontimeupdate = function(){ onPlayerTimeUpdate(playerElement[0]) }
0197     playerElement[0].play();
0198     setIsPlaying(true);
0199     setIsPaused(false);
0200     const currentSrc = props.items[playIndex].musicSrc;
0201     onReportAudioPlay(currentSrc);
0202   }
0203 
0204   // random supporter
0205 
0206   function getRandomMusicsupporter(){
0207     $.ajax({url: "https://"+window.location.hostname +"/json/fetchrandomsupporter/s/3"}).done(function(res) { 
0208       // console.log(res);
0209       setRandomSupporter(res.supporter)
0210     });
0211   }
0212 
0213   // time progress bar
0214 
0215   function onPlayerTimeUpdate(e){
0216     const playerElement = e.target;
0217     const newCurrentTrackTime = millisToMinutesAndSeconds(playerElement.currentTime);
0218     setCurrentTrackTime(newCurrentTrackTime);
0219     setCurrentTrackTimeSeconds(playerElement.duration);
0220     let newcurrentTrackDuration = playerElement.duration;
0221     if (isNaN(newcurrentTrackDuration)){ newcurrentTrackDuration = 0; }
0222     newcurrentTrackDuration = millisToMinutesAndSeconds(newcurrentTrackDuration);
0223     setcurrentTrackDuration(newcurrentTrackDuration );
0224     const newCurrentTrackProgress = (playerElement.currentTime / playerElement.duration) * 100;
0225     setCurrentTrackProgress(newCurrentTrackProgress);
0226     
0227     if (playerElement.currentTime === playerElement.duration){
0228       console.log('song ended');
0229       onNextTrackPlayClick();
0230     }
0231 
0232   }
0233 
0234   function millisToMinutesAndSeconds(time) {
0235     let minutes = Math.floor(time / 60);
0236     let seconds = time - minutes * 60;
0237     seconds = Math.floor(seconds);
0238     if (minutes < 10) minutes = "0" + minutes;
0239     if (seconds < 10) seconds = "0" +  seconds;
0240     const timestamp = minutes + ":" + seconds;
0241     return timestamp;
0242   }
0243 
0244   // volume
0245 
0246   function toggleAudioMuted(){
0247     const newIsMuted = isMuted === true ? false : true;
0248     const playerElement = document.getElementById("music-player-container").getElementsByTagName('audio');
0249     if (newIsMuted === true) playerElement[0].volume = 0;
0250     else playerElement[0].volume = audioVolume;
0251     setIsMuted(newIsMuted);
0252   }
0253 
0254   // playlist
0255 
0256   function togglePlaylistDisplay(){
0257     const newShowPlaylistValue = showPlaylist === true ? false : true;
0258     setShowPlaylist(newShowPlaylistValue);
0259   }
0260 
0261   // key press 
0262 
0263   function handleKeyPress(e){
0264     // console.log(e.key)
0265     if (e.key === 'Space'){
0266       if (isPlaying === true) onPauseClick();
0267       else onPlayClick();
0268     }
0269   }
0270 
0271   /* RENDER */
0272 
0273   let musicPlayerContainerCssClass = "";
0274   if (showPlaylist === true) musicPlayerContainerCssClass += "show-playlist ";
0275   if (isMobile === true) musicPlayerContainerCssClass += " is-mobile";
0276 
0277   const audioElVolume = isMuted === true ? 0.0 : audioVolume;
0278 
0279   const currentSrc = props.items[playIndex].musicSrc;
0280 
0281   return (
0282     <div id="music-player-container" className={musicPlayerContainerCssClass + " " + theme} onKeyPress={(e) => handleKeyPress(e)}> 
0283       <audio 
0284         volume={audioElVolume} 
0285         onTimeUpdate={(e) => onPlayerTimeUpdate(e)}  
0286         onLoadedMetadata={(e) => onPlayerTimeUpdate(e)}
0287         src={currentSrc}
0288         id="music-player-audio"></audio>
0289       <MusicPlayerControlPanel 
0290         playIndex={playIndex}
0291         isPlaying={isPlaying}
0292         isPaused={isPaused}
0293         isMuted={isMuted}
0294         isMobile={isMobile}
0295         audioVolume={audioVolume}
0296         currentTrackTime={currentTrackTime}
0297         currentTrackDuration={currentTrackDuration}
0298         currentTrackProgress={currentTrackProgress}
0299         items={props.items}
0300         theme={theme}
0301         setTheme={(val) => setTheme(val)}
0302         onUpdateCurrentTrackProgress={(val) => onUpdateCurrentTrackProgress(val)}
0303         onChangeAudioVolume={(val) => setAudioVolume(val)}
0304         onPlayClick={(reload) => onPlayClick(reload)}
0305         onPauseClick={onPauseClick}
0306         onPrevTrackPlayClick={onPrevTrackPlayClick}
0307         onNextTrackPlayClick={onNextTrackPlayClick}
0308         togglePlaylistDisplay={togglePlaylistDisplay}
0309         toggleAudioMuted={() => toggleAudioMuted()}
0310       />
0311       <MusicPlayerPlaylist 
0312         containerWidth={props.containerWidth}
0313         title={props.product.title}
0314         randomSupporter={randomSupporter}
0315         items={props.items}
0316         playIndex={playIndex}
0317         isPlaying={isPlaying}
0318         isPaused={isPaused}
0319         isMobile={isMobile}
0320         currentTrackTime={currentTrackTime}
0321         currentTrackDuration={currentTrackDuration}
0322         currentTrackProgress={currentTrackProgress}
0323         togglePlaylistDisplay={togglePlaylistDisplay}
0324         setPlayIndex={setPlayIndex}
0325         onPlayClick={(reload) => onPlayClick(reload)}
0326         onPauseClick={onPauseClick}
0327       />
0328     </div>
0329   )
0330 }
0331 
0332 // Hook
0333 function usePrevious(value) {
0334   // The ref object is a generic container whose current property is mutable ...
0335   // ... and can hold any value, similar to an instance property on a class
0336   const ref = useRef();
0337   
0338   // Store current value in ref
0339   useEffect(() => {
0340     ref.current = value;
0341   }, [value]); // Only re-run if value changes
0342   
0343   // Return previous value (happens before update in useEffect above)
0344   return ref.current;
0345 }
0346 
0347 function MusicPlayerControlPanel(props){
0348 
0349   // console.log(props);
0350 
0351   React.useEffect(() => {
0352     // console.log('music player controls panel');
0353     // console.log(props);
0354   },[])
0355 
0356   /* COMPONENT */
0357 
0358   function onChangeTrackProgressPosition(e){
0359     console.log(e);
0360     props.onUpdateCurrentTrackProgress(e);
0361   }
0362 
0363   function onAfterChangeTrackProgressPosition(e){
0364     // console.log(e);
0365   }
0366 
0367   function onChangeVolumeSliderPosition(e){
0368     if (props.isMuted === false){
0369       const newVolumeValue = e / 100;
0370       props.onChangeAudioVolume(newVolumeValue);      
0371     }
0372   }
0373 
0374   function onAfterChangeVolumeSliderPosition(e){
0375     // console.log(e);
0376   }
0377 
0378   function onVolumeIconClick(){
0379     props.toggleAudioMuted()
0380   }
0381 
0382   function onThemeSwitchClick(){
0383     const newThemeValue = props.theme === "dark" ? "light" : "dark";
0384     props.setTheme(newThemeValue);
0385   }
0386 
0387   /* DISPLAY */
0388 
0389   const playIndex = props.playIndex;
0390 
0391   // audio controls display
0392 
0393   const playButtonElement = (
0394     <svg fill="currentColor" preserveAspectRatio="xMidYMid meet" height="1em" width="1em" viewBox="0 0 40 40" className="play-icon">
0395         <g><path d="m20.1 2.9q4.7 0 8.6 2.3t6.3 6.2 2.3 8.6-2.3 8.6-6.3 6.2-8.6 2.3-8.6-2.3-6.2-6.2-2.3-8.6 2.3-8.6 6.2-6.2 8.6-2.3z m8.6 18.3q0.7-0.4 0.7-1.2t-0.7-1.2l-12.1-7.2q-0.7-0.4-1.5 0-0.7 0.4-0.7 1.3v14.2q0 0.9 0.7 1.3 0.4 0.2 0.8 0.2 0.3 0 0.7-0.2z"></path></g>
0396     </svg>
0397   )
0398 
0399   const pauseButtonElement = (
0400       <svg fill="currentColor" preserveAspectRatio="xMidYMid meet" height="1em" width="1em" viewBox="0 0 40 40" className="pause-icon">
0401           <g><path d="m18.7 26.4v-12.8q0-0.3-0.2-0.5t-0.5-0.2h-5.7q-0.3 0-0.5 0.2t-0.2 0.5v12.8q0 0.3 0.2 0.5t0.5 0.2h5.7q0.3 0 0.5-0.2t0.2-0.5z m10 0v-12.8q0-0.3-0.2-0.5t-0.5-0.2h-5.7q-0.3 0-0.5 0.2t-0.2 0.5v12.8q0 0.3 0.2 0.5t0.5 0.2h5.7q0.3 0 0.5-0.2t0.2-0.5z m8.6-6.4q0 4.7-2.3 8.6t-6.3 6.2-8.6 2.3-8.6-2.3-6.2-6.2-2.3-8.6 2.3-8.6 6.2-6.2 8.6-2.3 8.6 2.3 6.3 6.2 2.3 8.6z"></path></g>
0402       </svg>
0403   )
0404 
0405   const prevButtonElement = (
0406       <svg fill="currentColor" preserveAspectRatio="xMidYMid meet" height="1em" width="1em" viewBox="0 0 40 40" className="prev-icon">
0407           <g><path d="m15.9 20l14.1-10v20z m-5.9-10h3.4v20h-3.4v-20z"></path></g>
0408       </svg>
0409   )
0410 
0411   const nextButtonElement = (
0412       <svg fill="currentColor" preserveAspectRatio="xMidYMid meet" height="1em" width="1em" viewBox="0 0 40 40" className="next-icon">
0413           <g><path d="m26.6 10h3.4v20h-3.4v-20z m-16.6 20v-20l14.1 10z"></path></g>
0414       </svg>
0415   )
0416 
0417   let playButtonDisplay;
0418   if (props.isPlaying === true){
0419     if (props.isMobile === true) playButtonDisplay = <span onTouchStart={() => props.onPauseClick()}>{pauseButtonElement}</span>
0420     else playButtonDisplay = <span onClick={() => props.onPauseClick()}>{pauseButtonElement}</span>
0421   } else {
0422     if (props.isMobile === true)  playButtonDisplay = <span onTouchStart={() => props.onPlayClick()}>{playButtonElement}</span>
0423     else  playButtonDisplay = <span onClick={() => props.onPlayClick()}>{playButtonElement}</span>
0424   }
0425 
0426   let audioControlsDisplay;
0427 
0428   if (props.isMobile === true){
0429     audioControlsDisplay = (
0430       <div className="music-player-audio-control">
0431         <span onTouchStart={() => props.onPrevTrackPlayClick()}>{prevButtonElement}</span>
0432         {playButtonDisplay}
0433         <span onTouchStart={() => props.onNextTrackPlayClick()}>{nextButtonElement}</span>
0434       </div>
0435     )
0436   } else {
0437     audioControlsDisplay = (
0438       <div className="music-player-audio-control">
0439         <span onClick={() => props.onPrevTrackPlayClick()}>{prevButtonElement}</span>
0440         {playButtonDisplay}
0441         <span onClick={() => props.onNextTrackPlayClick()}>{nextButtonElement}</span>
0442       </div>
0443     )
0444   }
0445 
0446   // volume control
0447 
0448   const volumeIcon = (
0449     <svg fill="currentColor" preserveAspectRatio="xMidYMid meet" height="1em" width="1em" viewBox="0 0 40 40" style={{"verticalAlign":"middle"}}>
0450       <g><path d="m23.4 5.4c6.7 1.5 11.6 7.5 11.6 14.6s-4.9 13.1-11.6 14.6v-3.4c4.8-1.4 8.2-5.9 8.2-11.2s-3.4-9.8-8.2-11.2v-3.4z m4.1 14.6c0 3-1.6 5.5-4.1 6.7v-13.4c2.5 1.2 4.1 3.7 4.1 6.7z m-22.5-5h6.6l8.4-8.4v26.8l-8.4-8.4h-6.6v-10z"></path></g>
0451     </svg>
0452   )
0453 
0454   const noVolumeIcon = (
0455     <svg fill="currentColor" preserveAspectRatio="xMidYMid meet" height="1em" width="1em" viewBox="0 0 40 40"  style={{"verticalAlign":"middle"}}>
0456       <g><path d="m20 6.6v7.1l-3.5-3.5z m-12.9-1.6l27.9 27.9-2.1 2.1-3.4-3.4c-1.8 1.4-3.9 2.5-6.1 3v-3.4c1.4-0.4 2.6-1.1 3.7-2l-7.1-7.1v11.3l-8.4-8.4h-6.6v-10h7.9l-7.9-7.9z m24.5 15c0-5.3-3.4-9.8-8.2-11.2v-3.4c6.7 1.5 11.6 7.5 11.6 14.6 0 2.5-0.6 4.9-1.7 7l-2.5-2.6c0.5-1.4 0.8-2.8 0.8-4.4z m-4.1 0c0 0.4 0 0.7-0.1 1l-4-4.1v-3.6c2.5 1.2 4.1 3.7 4.1 6.7z"></path></g>
0457     </svg>
0458   )
0459 
0460   const volumeIconDisplay = props.isMuted === false ? volumeIcon : noVolumeIcon;
0461   let musicPlayerVolumeControlCssClass = "music-player-volume-control";
0462   if (props.isMuted) musicPlayerVolumeControlCssClass += " is-muted";
0463   
0464   const volumeControlDisplay = (
0465       <div className={musicPlayerVolumeControlCssClass}>
0466         <span className="volume-icon" onClick={onVolumeIconClick}>
0467           {volumeIconDisplay}
0468         </span>
0469         <span className="volume-bar-container progress_bar">
0470             <Slider 
0471               min={0}
0472               max={100}
0473               value={props.audioVolume * 100}
0474               vertical={props.isMobile ? false : true}
0475               onChange={onChangeVolumeSliderPosition}
0476               onAfterChange={onAfterChangeVolumeSliderPosition}
0477             />
0478         </span>
0479       </div>
0480     );
0481   
0482   // cover 
0483 
0484   const musicPlayerCoverDisplay = (
0485     <div className="music-player-cover">
0486       <figure><img src={props.items[playIndex].cover}/></figure>
0487     </div>
0488   )
0489 
0490   // title
0491 
0492   const musicPlayerTitleDisplay = (
0493     <div className="music-player-track-title">
0494       <h2>{props.items[playIndex].title}</h2>
0495     </div>
0496   )
0497 
0498   // time display
0499 
0500   let currentTrackTimeDisplay = props.currentTrackTime;
0501   if (props.currentTrackTime === 0){
0502     currentTrackTimeDisplay = '00:00'
0503   }
0504 
0505   let currentTrackDurationDisplay = props.currentTrackDuration;
0506   if (props.currentTrackDuration === 0){
0507     currentTrackDurationDisplay = <span className="infinite">&infin;</span>
0508   }
0509 
0510   const musicPlayerTimeDisplay = (
0511     <div className="music-player-time-display">
0512       <span className="current-track-time">{currentTrackTimeDisplay} </span>
0513       <span className="current-track-progress">
0514         <Slider 
0515           min={0}
0516           max={100}
0517           value={props.currentTrackProgress}
0518           onChange={onChangeTrackProgressPosition}
0519           onAfterChange={onAfterChangeTrackProgressPosition}
0520         />
0521       </span>
0522       <span className="current-track-duration">{currentTrackDurationDisplay}</span>
0523     </div>
0524   )
0525 
0526   // mobile / desktop switch display
0527 
0528   let musicPlayerControlPanelDisplay;
0529   if (props.isMobile === true){
0530 
0531     musicPlayerControlPanelDisplay = (
0532       <div className="mobile-control-panel-wrapper">
0533         {musicPlayerTitleDisplay}
0534         {musicPlayerCoverDisplay}
0535         {musicPlayerTimeDisplay}
0536         <div className="music-player-controls-bar">
0537           <div className="music-player-controls-wrapper">
0538             {audioControlsDisplay}
0539             <div className="bottom-controls">
0540               {volumeControlDisplay}
0541               <div className="playlist-toggle-container">
0542                 <span className="playlist-toggle-button" onTouchStart={() => props.togglePlaylistDisplay()}>
0543                   <svg fill="currentColor" preserveAspectRatio="xMidYMid meet" height="1em" width="1em" viewBox="0 0 40 40" style={{"vertical-align": "middle"}}>
0544                     <g><path d="m28.4 10h8.2v3.4h-5v15c0 2.7-2.2 5-5 5s-5-2.3-5-5 2.3-5 5-5c0.6 0 1.2 0.1 1.8 0.3v-13.7z m-23.4 16.6v-3.2h13.4v3.2h-13.4z m20-10v3.4h-20v-3.4h20z m0-6.6v3.4h-20v-3.4h20z"></path></g>
0545                   </svg>
0546                 </span>
0547               </div>
0548             </div>
0549           </div>
0550         </div>
0551       </div>
0552     )
0553   
0554   } else {
0555     
0556     let themeSwitchCssClass = "theme-switch-container rc-switch ";
0557     /*<div className="theme-switch-wrapper">
0558       <span className="theme-switch">
0559         <button onClick={() => onThemeSwitchClick()} type="button" role="switch" aria-checked="false" className={ themeSwitchCssClass }>
0560           <span className="rc-switch-inner">{props.theme === "dark" ? "light" : "dark"}</span>
0561         </button>
0562       </span>
0563     </div>*/
0564 
0565     if (props.theme === "light") themeSwitchCssClass += " checked";
0566 
0567     musicPlayerControlPanelDisplay = (
0568       <div className="desktop-control-panel-wrapper">
0569         {musicPlayerCoverDisplay}
0570         {musicPlayerTitleDisplay}
0571         {musicPlayerTimeDisplay}
0572         <div className="music-player-controls-bar">
0573           <div className="music-player-controls-wrapper">
0574               {audioControlsDisplay}
0575               {volumeControlDisplay}
0576               <div className="playlist-toggle-container">
0577                 <span className="playlist-toggle-button" onClick={() => props.togglePlaylistDisplay()}>PL</span>
0578               </div>
0579           </div>
0580         </div>
0581       </div>
0582     )
0583   }
0584 
0585   /* RENDER */
0586 
0587   return (
0588     <div id="music-player-control-panel">
0589       {musicPlayerControlPanelDisplay}
0590     </div>
0591   )
0592 }
0593 
0594 function MusicPlayerPlaylist(props){
0595 
0596   function onMusicPlayerPlaylistItemClick(val){
0597     if (props.isPlaying === false){
0598       if (props.playIndex === val) props.onPlayClick();
0599       // else props.onPlayClick(true,props.playIndex);
0600     }
0601     else {
0602       if (props.playIndex === val) props.onPauseClick();
0603       // else props.onPlayClick(true,props.playIndex);
0604     }
0605     props.setPlayIndex(val);
0606   }
0607 
0608   const musicPlayerPlaylistItems = props.items.map((item,index) => (
0609     <MusicPlayerPlaylistItem 
0610       key={index}
0611       index={index}
0612       item={item}
0613       playIndex={props.playIndex}
0614       isPlaying={props.isPlaying}
0615       isPaused={props.isPaused}
0616       isMobile={props.isMobile}
0617       onMusicPlayerPlaylistItemClick={(val) => onMusicPlayerPlaylistItemClick(val)}
0618     />
0619   ));
0620 
0621   const musicPlayerPlaylistDisplay = <ul>{musicPlayerPlaylistItems}</ul>
0622   
0623 
0624   let randomSupporterDisplay;
0625   if (props.randomSupporter && props.randomSupporter !== null){
0626     randomSupporterDisplay = (
0627       <div id="music-sponsor-display">
0628         <span>made possible by supporters like</span>
0629         <span className="sponsor-avatar">
0630           <a href={"/u/" + props.randomSupporter.username}>
0631             <img src={props.randomSupporter.profile_image_url}/>
0632           </a>
0633         </span>
0634         <span>
0635           {props.randomSupporter.username}
0636         </span>
0637       </div>
0638     )
0639   }
0640 
0641   let closeButtonDisplay = <a className="toggle-playlist" onClick={props.togglePlaylistDisplay}>X</a>
0642   if (props.isMobile === true) closeButtonDisplay = <a className="toggle-playlist" onTouchStart={props.togglePlaylistDisplay}>X</a>
0643 
0644   return (
0645     <div id="music-player-playlist-panel">
0646       <div id="music-player-playlist-header">
0647         <h2>{props.title + " / " + props.items.length }</h2>
0648         {closeButtonDisplay}
0649       </div>
0650       <div id="music-player-playlist">
0651         <Scrollbars
0652           width={props.containerWidth / 2}
0653           height={250}
0654         >
0655           {musicPlayerPlaylistDisplay}
0656         </Scrollbars>
0657       </div>
0658       <div id="music-player-playlist-footer">
0659         {randomSupporterDisplay}
0660       </div>
0661     </div>
0662   )
0663 }
0664 
0665 function MusicPlayerPlaylistItem(props){
0666 
0667   const playButtonElement = (
0668     <svg fill="currentColor" preserveAspectRatio="xMidYMid meet" height="1em" width="1em" viewBox="0 0 40 40" className="play-icon">
0669         <g><path d="m20.1 2.9q4.7 0 8.6 2.3t6.3 6.2 2.3 8.6-2.3 8.6-6.3 6.2-8.6 2.3-8.6-2.3-6.2-6.2-2.3-8.6 2.3-8.6 6.2-6.2 8.6-2.3z m8.6 18.3q0.7-0.4 0.7-1.2t-0.7-1.2l-12.1-7.2q-0.7-0.4-1.5 0-0.7 0.4-0.7 1.3v14.2q0 0.9 0.7 1.3 0.4 0.2 0.8 0.2 0.3 0 0.7-0.2z"></path></g>
0670     </svg>
0671   )
0672 
0673   const pauseButtonElement = (
0674       <svg fill="currentColor" preserveAspectRatio="xMidYMid meet" height="1em" width="1em" viewBox="0 0 40 40" className="pause-icon">
0675           <g><path d="m18.7 26.4v-12.8q0-0.3-0.2-0.5t-0.5-0.2h-5.7q-0.3 0-0.5 0.2t-0.2 0.5v12.8q0 0.3 0.2 0.5t0.5 0.2h5.7q0.3 0 0.5-0.2t0.2-0.5z m10 0v-12.8q0-0.3-0.2-0.5t-0.5-0.2h-5.7q-0.3 0-0.5 0.2t-0.2 0.5v12.8q0 0.3 0.2 0.5t0.5 0.2h5.7q0.3 0 0.5-0.2t0.2-0.5z m8.6-6.4q0 4.7-2.3 8.6t-6.3 6.2-8.6 2.3-8.6-2.3-6.2-6.2-2.3-8.6 2.3-8.6 6.2-6.2 8.6-2.3 8.6 2.3 6.3 6.2 2.3 8.6z"></path></g>
0676       </svg>
0677   )
0678 
0679   const playlistItemPlayButtonDisplay = props.playIndex === props.index ? props.isPlaying === true ? pauseButtonElement : playButtonElement : '';
0680   const playlistItemCssClass =  props.playIndex === props.index ? props.isPlaying === true ? 'is-playing' : 'is-paused' : '';
0681 
0682   let musicPlayerPlaylistItemDisplay;
0683   if (props.isMobile === true){
0684     musicPlayerPlaylistItemDisplay = (
0685       <a onTouchStart={() => props.onMusicPlayerPlaylistItemClick(props.index)}>
0686         {playlistItemPlayButtonDisplay}
0687         {props.item.title}
0688       </a>
0689     )
0690   } else {
0691     musicPlayerPlaylistItemDisplay = (
0692       <a onClick={() => props.onMusicPlayerPlaylistItemClick(props.index)}>
0693         {playlistItemPlayButtonDisplay}
0694         {props.item.title}
0695       </a>
0696     )    
0697   }
0698 
0699   return (
0700     <li className={"music-player-playlist-item " + playlistItemCssClass} >
0701       {musicPlayerPlaylistItemDisplay}
0702     </li>
0703   )
0704 }
0705 
0706 export default MusicPlayerWrapper;