{"version":3,"sources":["api/index.js","constants/action_types.js","actions/albums.js","actions/song.js","actions/currentalbum.js","actions/isplaying.js","components/albumcontainer/albums/album/song/song.js","components/albumcontainer/albums/album/styles.js","components/albumcontainer/albums/album/album.js","components/albumcontainer/albums/albums.js","components/albumcontainer/albumcontainer.js","components/audioplayer/styles.js","components/audioplayer/formattime/formattime.js","components/audioplayer/song/song.js","components/audioplayer/trackbar/trackbar.js","components/audioplayer/audio.js","actions/togglerepeat.js","components/searchfield/searchfield.js","App.js","actions/toggleArtworkDisplay.js","reducers/albums.js","reducers/song.js","reducers/currentalbum.js","reducers/isplaying.js","reducers/toggleArtworkDisplay.js","reducers/togglerepeat.js","reducers/index.js","index.js"],"names":["FETCH_ALL","UPDATE","CLEAR","UPDATE_CURRENT","PREVSONG","NEXTSONG","PLAY","PAUSE","REPEAT","REPEATSONG","UPDATEPLAYING","SETTOGGLEIMAGES","getPosts","quality","async","data","axios","get","concat","api","dispatch","type","payload","err","console","trace","set_song","song","navigator","mediaSession","metadata","title","artist","album","update_current_album_and_song","current_albums","album_index","song_index","setIsPlaying","state","Song","_ref","useDispatch","all_albums","useSelector","albums","_jsx","className","onClick","handle_click","children","makeStyles","cont","width","img","Album","displayImages","image_handler","selected","toggleSelected","useState","classes","useStyles","_jsxs","src","cover","alt","songs","map","index","_id","Albums","length","Grid","container","item","xs","md","lg","xl","AlbumContainer","_Fragment","audio_bar","formatTime","time","isNaN","seconds","Math","floor","minutes","disk","track","Trackbar","currentTime","totalTime","onTimeUpdate","currentPercentProgress","setCurrentPercentProgress","useEffect","calculate_clicked_time","evt","scuffalicious","document","querySelector","clickPos","pageX","barStart","getBoundingClientRect","left","window","scrollX","barWidth","offsetWidth","style","background","onMouseDown","updateTimeOnMove","move_evt","addEventListener","removeEventListener","handleTimeDrag","Audio","store","useStore","music_player","setTotalTime","setCurrentTime","playing","isplaying","repeat","clickedTime","setClickedTime","action_type","log","play","pause","afterUpdate","current_data","getState","current","setActionHandler","current_song","autoPlay","songUrl","onPlay","e","target","duration","onEnded","ref","min","max","step","defaultValue","onChange","volume","value","SearchField","matches","setMatches","currentAlbumIndex","setCurrentAlbumIndex","scuf","searchInputRef","useRef","handleClick","match","parentElement","firstChild","ctrlKey","key","preventDefault","focus","onSubmit","blur","handleSubmit","display","i","toLowerCase","includes","push","handleUpdate","onKeyDown","handleKeyDown","margin","color","App","toggleArtworkDisplay","handle_buttons","album_handler","arguments","undefined","action","sort","a","b","song_handler","currentalbum_handler","tempstore","artwork","sizes","playing_handler","displaying","repeat_handler","combineReducers","composeEnhancers","__REDUX_DEVTOOLS_EXTENSION_COMPOSE__","compose","createStore","reducers","applyMiddleware","thunk","MediaMetadata","ReactDOM","render","Provider","getElementById"],"mappings":"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","file":"static/js/main.320d16ff.chunk.js","sourcesContent":["import axios from \"axios\";\r\n\r\nconst url = \"https://scuffedwebsite.com/Tsunami/api\";\r\n\r\n/**\r\n * Going to leave the shorthand as standard and the verbose as comments\r\n */\r\n\r\n/**\r\n * \r\n * @param {String} quality\r\n * As of now either mp3 or native depending on quality choice\r\n * @returns {Object[]}\r\n */\r\n\r\nexport const fetchPosts = async (quality) => await axios.get(`${url}/${quality}`);\r\n\r\n/* export const fetchPosts = async (quality) =>\r\n{\r\n return await axios.get(`${url}/${quality}`);\r\n} */\r\n\r\n","export const FETCH_ALL = \"FETCH_ALL\";\r\nexport const UPDATE = \"UPDATE\";\r\nexport const SORT = \"SORT\";\r\nexport const CLEAR = \"CLEAR\";\r\nexport const UPDATE_CURRENT = \"UPDATE_CURRENT\";\r\nexport const PREVSONG = \"PREV\";\r\nexport const NEXTSONG = \"NEXT\";\r\nexport const PLAY = \"PLAY\";\r\nexport const PAUSE = \"PAUSE\";\r\nexport const REPEAT = \"REPEAT\";\r\nexport const REPEATSONG = \"REPEATSONG\";\r\nexport const UPDATEPLAYING = \"UPDATEPLAYING\";\r\nexport const SETSHUFFLE = \"SETSHUFFLE\";\r\nexport const SETNOTSHUFFLE = \"SETNOTSHUFFLE\";\r\n//export const UPDATESONGINDEX = \"UPDATESONGINDEX\";\r\nexport const SETTOGGLEIMAGES = \"SETTOGGLEIMAGES\";","import * as api from \"../api/index\"\r\nimport { FETCH_ALL } from \"./../constants/action_types.js\"\r\n\r\nexport const getPosts = (quality) => async (dispatch) =>\r\n{\r\n try\r\n {\r\n \r\n /**\r\n * I'm not sure whether I prefer object destructuring\r\n * or dot notation yet, so I'll probably be using both\r\n * during this project\r\n */\r\n\r\n const { data } = await api.fetchPosts(quality);\r\n dispatch({ type: FETCH_ALL, payload: data });\r\n }\r\n catch (err)\r\n {\r\n console.trace(err);\r\n }\r\n}\r\n","import { UPDATE, CLEAR } from \"./../constants/action_types\";\r\nexport const set_song = (song) => async (dispatch) =>\r\n{\r\n try\r\n {\r\n navigator.mediaSession.metadata.title = song.title;\r\n navigator.mediaSession.metadata.artist = song.artist;\r\n navigator.mediaSession.metadata.album = song.album;\r\n dispatch({ type: UPDATE, payload: song });\r\n }\r\n catch (err)\r\n {\r\n console.trace(err);\r\n }\r\n}\r\n\r\nexport const clear_song = () => async (dispatch) =>\r\n{\r\n try\r\n {\r\n dispatch({ type: CLEAR });\r\n }\r\n catch (err)\r\n {\r\n console.trace(err);\r\n }\r\n}\r\n\r\n","import { UPDATE_CURRENT, PREVSONG, NEXTSONG } from \"./../constants/action_types\";\r\n\r\nexport const update_current_album_and_song = (current_albums, album_index, song_index) => async (dispatch) =>\r\n{\r\n try\r\n {\r\n dispatch({\r\n type: UPDATE_CURRENT, payload: {\r\n current_albums,\r\n album_index,\r\n song_index\r\n }\r\n });\r\n }\r\n catch (err)\r\n {\r\n console.trace(err);\r\n }\r\n}\r\n\r\nexport const prev_song = () => async (dispatch) =>\r\n{\r\n try\r\n {\r\n dispatch({ type: PREVSONG });\r\n }\r\n catch (err)\r\n {\r\n console.trace(err);\r\n }\r\n}\r\n\r\nexport const next_song = () => async (dispatch) =>\r\n{\r\n try\r\n {\r\n dispatch({ type: NEXTSONG });\r\n }\r\n catch (err)\r\n {\r\n console.trace(err);\r\n }\r\n}","import { UPDATEPLAYING } from \"./../constants/action_types.js\";\r\n\r\nexport const setIsPlaying = (state) => async (dispatch) =>\r\n{\r\n try\r\n {\r\n dispatch({ type: UPDATEPLAYING, payload: state });\r\n }\r\n catch (err)\r\n {\r\n console.trace(err);\r\n }\r\n}\r\n","import { useDispatch, useSelector } from \"react-redux\";\r\n\r\nimport { set_song } from \"../../../../../actions/song\";\r\nimport { update_current_album_and_song } from \"../../../../../actions/currentalbum\";\r\nimport { setIsPlaying } from \"../../../../../actions/isplaying.js\";\r\n\r\nconst Song = ({ album_index, song, song_index }) =>\r\n{\r\n\r\n const dispatch = useDispatch();\r\n\r\n const all_albums = useSelector((state) => state.albums);\r\n\r\n const handle_click = (song) =>\r\n {\r\n dispatch(update_current_album_and_song(all_albums, album_index, song_index));\r\n dispatch(set_song(song));\r\n dispatch(setIsPlaying(true));\r\n }\r\n\r\n return (\r\n <div className={\"songDiv\"} onClick={() => handle_click(song)}>{song.title}</div>\r\n );\r\n}\r\n\r\nexport default Song;\r\n","import { makeStyles } from \"@material-ui/core/styles\";\r\n\r\nexport default makeStyles(() => ({\r\n cont: {\r\n width: \"100%\",\r\n },\r\n img: {\r\n width: \"100%\",\r\n }\r\n}))\r\n","import { useState } from \"react\";\r\nimport { useSelector } from \"react-redux\";\r\nimport Song from \"./song/song.js\";\r\nimport useStyles from \"./styles.js\";\r\n\r\nconst Album = ({ album }) =>\r\n{\r\n\r\n const displayImages = useSelector((state) => state.image_handler);\r\n const [selected, toggleSelected] = useState(false);\r\n const classes = useStyles();\r\n\r\n return (\r\n <div className={classes.cont}>\r\n\r\n {displayImages ?\r\n <img className={classes.img} src={album.cover} alt={album.album} onClick={() => toggleSelected(!selected)} />\r\n :\r\n <div onClick={() => toggleSelected(!selected)}>{album.album}</div>\r\n }\r\n {selected ?\r\n (\r\n <div className=\"songsContainer\">\r\n {album.songs.map((song, song_index) => (\r\n <Song key={song._id} album_index={album.index} song={song} song_index={song_index} />\r\n ))}\r\n </div>\r\n )\r\n : <div />\r\n }\r\n </div>\r\n );\r\n}\r\n\r\nexport default Album;","import { useSelector } from \"react-redux\"\r\nimport { Grid } from \"@material-ui/core\"\r\nimport Album from \"./album/album.js\";\r\n\r\n\r\nconst Albums = () =>\r\n{\r\n\r\n\r\n const albums = useSelector((state) => state.albums);\r\n\r\n /**\r\n * The reason for parentheses being used is because of jsx\r\n * and the nature of the return statement\r\n */\r\n\r\n return (\r\n !albums.length\r\n ? (\r\n <div/>\r\n )\r\n : (\r\n <Grid container>\r\n {albums.map((album) => (\r\n <Grid key={album._id} item xs={12} md={4} lg={4} xl={3}>\r\n <Album album={album} />\r\n </Grid>\r\n ))}\r\n </Grid>\r\n )\r\n );\r\n}\r\n\r\nexport default Albums;","import Albums from \"./albums/albums.js\";\r\n\r\nconst AlbumContainer = () =>\r\n{\r\n return (\r\n <>\r\n <Albums />\r\n </>\r\n );\r\n}\r\n\r\nexport default AlbumContainer;","import { makeStyles } from \"@material-ui/core/styles\";\r\n\r\nexport default makeStyles(() => ({\r\n audio_bar: {\r\n \"margin-top\": \"1rem\",\r\n \"padding\": \"0rem\",\r\n \"background-color\": \"rgb(20,20,20)\",\r\n \"position\": \"fixed\",\r\n \"bottom\": \"0px\",\r\n \"left\": \"0\",\r\n \"width\": \"100%\"\r\n }\r\n}));\r\n\r\n","\r\nconst formatTime = (time) =>\r\n{\r\n if (isNaN(time)) return \"NaN\";\r\n\r\n /**\r\n * How come there are so many bad examples of how to do this online\r\n * when it's literally just 3 lines of code\r\n */\r\n \r\n let seconds = Math.floor(time % 60);\r\n let minutes = Math.floor(((time / 60) % 60));\r\n return `${minutes}:${seconds < 10 ? '0' + seconds : seconds}`;\r\n}\r\n\r\nexport default formatTime;","const Song = ({ song }) =>\r\n{\r\n\r\n return (\r\n <div>\r\n Artist: {song.artist}<br />\r\n Title: {song.title}<br />\r\n {song.disk ? (\r\n <div>\r\n Disk {song.disk}\r\n <br />\r\n </div>)\r\n : \"\"\r\n }\r\n Track: {song.track}<br />\r\n Album: {song.album}\r\n </div>\r\n );\r\n}\r\n\r\nexport default Song;\r\n","import { useEffect, useState } from \"react\";\r\n\r\nimport \"./styles.css\"\r\nconst Trackbar = ({ currentTime, totalTime, onTimeUpdate }) =>\r\n{\r\n\r\n const [currentPercentProgress, setCurrentPercentProgress] = useState(0);\r\n\r\n useEffect(() =>\r\n {\r\n setCurrentPercentProgress((currentTime / totalTime) * 100)\r\n }, [currentTime, totalTime])\r\n\r\n const calculate_clicked_time = (evt) =>\r\n {\r\n const scuffalicious = document.querySelector(\".bar\");\r\n const clickPos = evt.pageX;\r\n const barStart = scuffalicious.getBoundingClientRect().left + window.scrollX;\r\n const barWidth = scuffalicious.offsetWidth;\r\n const clickPosInBar = clickPos - barStart;\r\n const timePerPixel = totalTime / barWidth;\r\n return (timePerPixel * clickPosInBar);\r\n }\r\n\r\n const handleTimeDrag = (evt) =>\r\n {\r\n onTimeUpdate(calculate_clicked_time(evt));\r\n\r\n const updateTimeOnMove = (move_evt) =>\r\n {\r\n onTimeUpdate(calculate_clicked_time(move_evt));\r\n }\r\n\r\n document.addEventListener(\"mousemove\", updateTimeOnMove);\r\n\r\n document.addEventListener(\"mouseup\", () =>\r\n {\r\n document.removeEventListener(\"mousemove\", updateTimeOnMove);\r\n })\r\n }\r\n\r\n return (\r\n <div>\r\n <div className=\"bar\">\r\n <div className=\"bar_progress\" style={{\r\n background: `linear-gradient(to right, #000 ${currentPercentProgress}%, white)`\r\n }} onMouseDown={(evt) => handleTimeDrag(evt)}>\r\n <span className=\"knob\" style={{ left: `${currentPercentProgress}%` }} />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default Trackbar;\r\n","import { useEffect, useState } from \"react\"\r\nimport { useDispatch, useSelector, useStore } from \"react-redux\";\r\n\r\n\r\nimport { setIsPlaying } from \"../../actions/isplaying\"\r\nimport { set_song } from \"../../actions/song\";\r\n\r\nimport { PREVSONG, NEXTSONG, PLAY, PAUSE, REPEAT, REPEATSONG } from \"../../constants/action_types\";\r\nimport { prev_song, next_song } from \"../../actions/currentalbum\";\r\n\r\nimport useStyles from \"./styles.js\";\r\n\r\nimport formatTime from \"./formattime/formattime.js\";\r\n\r\nimport Song from \"./song/song.js\";\r\nimport Trackbar from \"./trackbar/trackbar.js\";\r\nimport { toggleRepeat } from \"../../actions/togglerepeat\";\r\n\r\nconst Audio = () =>\r\n{\r\n\r\n const dispatch = useDispatch();\r\n\r\n /**\r\n * I should probably stick to using only useSelector or useStore\r\n * in the future\r\n */\r\n\r\n const store = useStore();\r\n\r\n const classes = useStyles();\r\n\r\n /**\r\n * Using refs can get highly messy so annotating this here\r\n * music_player is a ref to the main dom audio player\r\n */\r\n let music_player;\r\n\r\n const [totalTime, setTotalTime] = useState(0);\r\n const [currentTime, setCurrentTime] = useState(0);\r\n\r\n // Is song currently playing\r\n const playing = useSelector((state) => state.isplaying);\r\n // Is repeat song toggled\r\n const repeat = useSelector((state) => state.repeat);\r\n\r\n /**\r\n * Logic for handling clicks on bar\r\n */\r\n const [clickedTime, setClickedTime] = useState();\r\n\r\n useEffect(() =>\r\n {\r\n if (isNaN(clickedTime)) return;\r\n music_player.currentTime = clickedTime;\r\n }, [clickedTime, music_player])\r\n\r\n const afterUpdate = () =>\r\n {\r\n let current_data = store.getState().current;\r\n let song = current_data.album.songs[current_data.song_index];\r\n dispatch(set_song(song));\r\n }\r\n\r\n const repeatSong = () =>\r\n {\r\n music_player.currentTime = 0;\r\n music_player.play();\r\n }\r\n\r\n const handle_click = (action_type) =>\r\n {\r\n if (!music_player) return console.log(\"Choose a song before trying to play it.\");\r\n\r\n switch (action_type)\r\n {\r\n case PLAY:\r\n music_player.play();\r\n dispatch(setIsPlaying(!playing));\r\n break;\r\n case PAUSE:\r\n music_player.pause();\r\n dispatch(setIsPlaying(!playing));\r\n break;\r\n case PREVSONG:\r\n dispatch(prev_song(PREVSONG));\r\n dispatch(setIsPlaying(true));\r\n break;\r\n case NEXTSONG:\r\n dispatch(next_song(NEXTSONG));\r\n dispatch(setIsPlaying(true));\r\n break;\r\n case REPEAT:\r\n dispatch(toggleRepeat(REPEAT));\r\n break;\r\n case REPEATSONG:\r\n repeatSong();\r\n break;\r\n default:\r\n return console.log(\"Unknown action type\\nIf this happened something's either gone horribly wrong or you know what you're doing and are fucking with the console\");\r\n }\r\n afterUpdate();\r\n }\r\n\r\n\r\n navigator.mediaSession.setActionHandler(\"play\", () => handle_click(PLAY));\r\n navigator.mediaSession.setActionHandler(\"pause\", () => handle_click(PAUSE));\r\n navigator.mediaSession.setActionHandler(\"previoustrack\", () => handle_click(PREVSONG));\r\n navigator.mediaSession.setActionHandler(\"nexttrack\", () => handle_click(NEXTSONG));\r\n\r\n const current_song = useSelector((state) => state.song);\r\n\r\n return (\r\n <div className={classes.audio_bar}>\r\n {\r\n current_song._id\r\n ? (\r\n <div>\r\n <Song song={current_song} />\r\n <button onClick={() => handle_click(PREVSONG)}>\r\n Prev\r\n </button>\r\n {playing ?\r\n (\r\n <button onClick={() => handle_click(PAUSE)}>\r\n Pause\r\n </button>\r\n )\r\n : (\r\n <button onClick={() => handle_click(PLAY)}>\r\n Play\r\n </button>\r\n )}\r\n <button onClick={() => handle_click(NEXTSONG)}>\r\n Next\r\n </button>\r\n {repeat ?\r\n (\r\n <button onClick={() => handle_click(REPEAT)}>\r\n Stop Repeat\r\n </button>\r\n )\r\n : (\r\n <button onClick={() => handle_click(REPEAT)}>\r\n Repeat\r\n </button>\r\n )\r\n }\r\n\r\n <audio\r\n autoPlay src={current_song.songUrl}\r\n onPlay={(e) => setTotalTime(e.target.duration)}\r\n onTimeUpdate={(e) => setCurrentTime(e.target.currentTime)}\r\n onEnded={repeat ? () => handle_click(REPEATSONG) : () => handle_click(NEXTSONG)}\r\n ref={ref => music_player = ref}\r\n />\r\n\r\n <div>\r\n {formatTime(currentTime)} / {formatTime(totalTime)}\r\n </div>\r\n\r\n <input\r\n type=\"range\"\r\n min=\"0\"\r\n max=\"100\"\r\n step=\"1\"\r\n defaultValue=\"100\"\r\n onChange={(evt) => music_player.volume = (evt.target.value / 100)}\r\n />\r\n\r\n <Trackbar\r\n currentTime={currentTime}\r\n totalTime={totalTime}\r\n music_player={music_player}\r\n onTimeUpdate={(time) => setClickedTime(time)}\r\n />\r\n\r\n\r\n\r\n </div>\r\n )\r\n : (\r\n <div>\r\n Nothing playing right now\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default Audio;\r\n","import { REPEAT } from \"../constants/action_types\";\r\n\r\nexport const toggleRepeat = () => async (dispatch) =>\r\n{\r\n try\r\n {\r\n dispatch({ type: REPEAT });\r\n }\r\n catch (err)\r\n {\r\n console.trace(err);\r\n }\r\n}\r\n","import { useState, useRef } from \"react\";\r\nimport { useSelector, useDispatch } from \"react-redux\";\r\n\r\nimport { update_current_album_and_song } from \"../../actions/currentalbum\";\r\nimport { set_song } from \"../../actions/song\";\r\nimport { setIsPlaying } from \"../../actions/isplaying\";\r\n\r\nimport \"./searchfield.css\";\r\n\r\nconst SearchField = () =>\r\n{\r\n\r\n const dispatch = useDispatch();\r\n let [matches, setMatches] = useState([]);\r\n let [currentAlbumIndex, setCurrentAlbumIndex] = useState(-1);\r\n let albums = useSelector((state) => state.albums)\r\n let scuf = [];\r\n\r\n // Reference to input field\r\n const searchInputRef = useRef();\r\n\r\n const handleUpdate = (evt) =>\r\n {\r\n /// Like with most of this codebase, this code is bad\r\n /// I do not enjoy working in javascript and so i will not be fixing it\r\n\r\n scuf = [];\r\n setCurrentAlbumIndex(0);\r\n if (!evt.target.value.length) return setMatches(scuf);\r\n\r\n for (let i = 0; i < albums.length; i++)\r\n {\r\n /* if ((albums[i].album.substr(0, evt.target.value.length).toLowerCase()) === evt.target.value.toLowerCase())\r\n {\r\n scuf.push(albums[i]);\r\n } */\r\n if (albums[i].album.toLowerCase().includes(evt.target.value.toLowerCase()))\r\n {\r\n scuf.push(albums[i]);\r\n }\r\n }\r\n setMatches(scuf);\r\n\r\n }\r\n\r\n const handleKeyDown = (evt) =>\r\n {\r\n switch (evt.key)\r\n {\r\n case \"ArrowUp\":\r\n evt.preventDefault();\r\n currentAlbumIndex === 0 ? setCurrentAlbumIndex(matches.length - 1) : setCurrentAlbumIndex(currentAlbumIndex -= 1);\r\n break;\r\n case \"ArrowDown\":\r\n evt.preventDefault();\r\n currentAlbumIndex === matches.length - 1 ? setCurrentAlbumIndex(0) : setCurrentAlbumIndex(currentAlbumIndex += 1);\r\n break;\r\n case \"Enter\":\r\n if (!matches[currentAlbumIndex]) return;\r\n handleClick(evt, matches[currentAlbumIndex])\r\n break;\r\n default:\r\n return;\r\n }\r\n }\r\n\r\n const handleSubmit = (evt) =>\r\n {\r\n /**\r\n * Just clearing it, why it's a form I have no idea\r\n */\r\n evt.preventDefault();\r\n // Remove focus from input field\r\n searchInputRef.current.blur();\r\n scuf = [];\r\n setMatches(scuf);\r\n evt.target[0].value = \"\";\r\n }\r\n\r\n\r\n const handleClick = (evt, match) =>\r\n {\r\n\r\n /**\r\n * Lmao\r\n */\r\n\r\n dispatch(update_current_album_and_song(albums, match.index, 0));\r\n dispatch(set_song(match.songs[0]));\r\n dispatch(setIsPlaying(true));\r\n scuf = [];\r\n setMatches(scuf);\r\n evt.target.parentElement.parentElement.firstChild.value = \"\";\r\n }\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n // This is so scuffed\r\n // If searching, focus search field\r\n window.addEventListener(\"keydown\", (evt) =>\r\n {\r\n if (evt.ctrlKey && evt.key === \"f\")\r\n {\r\n evt.preventDefault();\r\n searchInputRef.current.focus();\r\n }\r\n });\r\n\r\n\r\n\r\n return (\r\n <>\r\n <form onSubmit={(evt) => handleSubmit(evt)} style={{ display: \"inline\" }}>\r\n <input ref={searchInputRef} onChange={(evt) => handleUpdate(evt)} onKeyDown={(evt) => handleKeyDown(evt)} style={{ background: \"black\", margin: \"2px\", color: \"white\" }} />\r\n <div className=\"searchContainer\">\r\n {matches.map((match, i) => (\r\n <div onClick={(evt) => handleClick(evt, match)}\r\n className={i !== currentAlbumIndex ? \"searchSuggestions\" : \"selectedSuggestion\"}\r\n key={i}>{match.album}</div>\r\n ))}\r\n </div>\r\n </form>\r\n </>\r\n );\r\n}\r\n\r\nexport default SearchField;\r\n","import { useDispatch } from \"react-redux\";\nimport { getPosts } from \"./actions/albums\"\nimport { clear_song } from \"./actions/song\"\nimport { aToggleArtworkDisplay } from \"./actions/toggleArtworkDisplay\"\n\nimport AlbumContainer from \"./components/albumcontainer/albumcontainer\";\nimport Audio from \"./components/audioplayer/audio\";\nimport SearchField from \"./components/searchfield/searchfield\";\n\n\nfunction App()\n{\n\n\n\n\n const dispatch = useDispatch();\n\n\n const toggleArtworkDisplay = () =>\n {\n dispatch(aToggleArtworkDisplay());\n }\n\n\n\n const handle_buttons = (type) =>\n {\n dispatch(clear_song());\n dispatch(getPosts(type));\n }\n\n return (\n <div>\n <button onClick={() => handle_buttons(\"mp3\")}>MP3</button>\n <button onClick={() => handle_buttons(\"native\")}>Native</button>\n {<button onClick={() => toggleArtworkDisplay()}>Art</button>}\n <SearchField />\n <Audio />\n <AlbumContainer />\n </div>\n );\n}\n\nexport default App;\n","import { SETTOGGLEIMAGES } from \"../constants/action_types.js\"\r\n\r\nexport const aToggleArtworkDisplay = () => async (dispatch) =>\r\n{\r\n try\r\n {\r\n dispatch({ type: SETTOGGLEIMAGES });\r\n }\r\n catch (err)\r\n {\r\n console.trace(err);\r\n }\r\n}\r\n","import { FETCH_ALL, SORT } from \"../constants/action_types.js\";\r\n\r\nconst album_handler = (albums = [], action) =>\r\n{\r\n switch (action.type)\r\n {\r\n case FETCH_ALL:\r\n let hold = [...action.payload];\r\n let sorted_albums = hold.sort((a, b) => a.album.toLowerCase() < b.album.toLowerCase() ? -1 : 1);\r\n let sorted_and_indexed_albums = sorted_albums.map((album, i) =>\r\n {\r\n return { ...album, index: i }\r\n })\r\n return sorted_and_indexed_albums;\r\n case SORT:\r\n return albums;\r\n default:\r\n return albums;\r\n }\r\n}\r\n\r\nexport default album_handler;\r\n","import { UPDATE, CLEAR } from \"../constants/action_types.js\"\r\nconst song_handler = (song = {}, action) =>\r\n{\r\n switch (action.type)\r\n {\r\n case UPDATE:\r\n return action.payload;\r\n case CLEAR:\r\n return {};\r\n default:\r\n return song;\r\n }\r\n}\r\n\r\nexport default song_handler;\r\n","import { UPDATE_CURRENT, PREVSONG, NEXTSONG } from \"../constants/action_types\";\r\n\r\nconst currentalbum_handler = (data = {\r\n albums: [],\r\n album: {\r\n songs: [],\r\n cover: \"\"\r\n },\r\n song_index: 0\r\n}, action) =>\r\n{\r\n let tempstore = { ...data };\r\n\r\n switch (action.type)\r\n {\r\n case UPDATE_CURRENT:\r\n tempstore.album = action.payload.current_albums[action.payload.album_index];\r\n tempstore.song_index = action.payload.song_index;\r\n navigator.mediaSession.metadata.artwork = [\r\n { src: tempstore.album.cover, sizes: \"96x96\", type: \"image/png\" },\r\n { src: tempstore.album.cover, sizes: \"128x128\", type: \"image/png\" },\r\n { src: tempstore.album.cover, sizes: \"192x192\", type: \"image/png\" },\r\n { src: tempstore.album.cover, sizes: \"256x256\", type: \"image/png\" },\r\n { src: tempstore.album.cover, sizes: \"384x384\", type: \"image/png\" },\r\n { src: tempstore.album.cover, sizes: \"512x512\", type: \"image/png\" },\r\n ];\r\n return tempstore;\r\n case PREVSONG:\r\n if (tempstore.song_index === 0)\r\n {\r\n tempstore.song_index = tempstore.album.songs.length - 1;\r\n }\r\n else\r\n {\r\n tempstore.song_index--;\r\n }\r\n return tempstore;\r\n case NEXTSONG:\r\n tempstore.song_index = (tempstore.song_index + 1) % tempstore.album.songs.length;\r\n return tempstore;\r\n default:\r\n return tempstore;\r\n }\r\n}\r\n\r\nexport default currentalbum_handler;","import { UPDATEPLAYING } from \"../constants/action_types.js\";\r\n\r\nconst playing_handler = (playing = false, action) =>\r\n{\r\n switch (action.type)\r\n {\r\n case UPDATEPLAYING:\r\n return action.payload;\r\n default:\r\n return playing;\r\n }\r\n}\r\n\r\nexport default playing_handler;","import { SETTOGGLEIMAGES } from \"../constants/action_types.js\";\r\n\r\nconst image_handler = (displaying = false, action) =>\r\n{\r\n switch (action.type)\r\n {\r\n case SETTOGGLEIMAGES:\r\n return !displaying;\r\n default:\r\n return displaying;\r\n }\r\n}\r\n\r\nexport default image_handler;\r\n","import { REPEAT } from \"../constants/action_types.js\";\r\n\r\nconst repeat_handler = (repeat = false, action) =>\r\n{\r\n switch (action.type)\r\n {\r\n case REPEAT:\r\n return !repeat;\r\n default:\r\n return repeat;\r\n }\r\n}\r\n\r\nexport default repeat_handler;","import { combineReducers } from \"redux\";\r\nimport albums from \"./albums\";\r\nimport song from \"./song\";\r\nimport current from \"./currentalbum\";\r\nimport isplaying from \"./isplaying\";\r\nimport image_handler from \"./toggleArtworkDisplay\";\r\nimport repeat from \"./togglerepeat\";\r\nexport default combineReducers({ albums, song, current, isplaying, image_handler, repeat });\r\n","import ReactDOM from 'react-dom';\n\nimport { createStore, applyMiddleware, compose } from \"redux\";\nimport { Provider } from \"react-redux\";\nimport thunk from \"redux-thunk\";\n\nimport App from './App';\nimport reducers from \"./reducers/index.js\";\n\nimport './index.css';\n\n\n/**\n * Required middleware for redux dev chrome tool\n * which is a fucking godsend btw\n */\n\nconst composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;\n\nexport const store = createStore(reducers, /* preloadedState, */ composeEnhancers(applyMiddleware(thunk)));\n\nif (\"mediaSession\" in navigator)\n{\n navigator.mediaSession.metadata = new window.MediaMetadata({\n title: \"\",\n album: \"\",\n artist: \"\"\n })\n}\n\nReactDOM.render(\n <Provider store={store}>\n <App />\n </Provider>,\n document.getElementById('root')\n);\n\n"],"sourceRoot":""}