diff --git a/src/actions/detailsActions.js b/src/actions/detailsActions.js index 2e481b3..db9b4b8 100644 --- a/src/actions/detailsActions.js +++ b/src/actions/detailsActions.js @@ -1,6 +1,7 @@ import { LOAD_DETAILS, CLEAR_DETAILS, SET_DETAILS_LOADING, DISPLAY_WARNING } from './types' import { SONG_DETAILS } from '../constants/views' import { BEATSAVER_BASE_URL, BSABER_BASE_URL } from '../constants/urls' +import { makeUrl } from '../utilities' import AdmZip from 'adm-zip' import { hashAndWriteToMetadata } from './queueActions' @@ -61,7 +62,7 @@ export const loadDetailsFromKey = key => (dispatch, getState) => { }) setView(SONG_DETAILS)(dispatch, getState) if((/^[a-f0-9]+$/).test(key)) { - fetch(`${BEATSAVER_BASE_URL}/api/maps/detail/${key}`) + fetch(makeUrl(BEATSAVER_BASE_URL, `/api/maps/detail/${key}`)) .then(res => { if(res.status === 404){ dispatch({ @@ -75,7 +76,7 @@ export const loadDetailsFromKey = key => (dispatch, getState) => { }) .then(res => res.json()) .then(details => { - fetch(`${BEATSAVER_BASE_URL}${details.downloadURL}`) + fetch(makeUrl(BEATSAVER_BASE_URL, details.downloadURL)) .then(res => res.arrayBuffer()) .then(data => { let zip = new AdmZip(new Buffer(data)) @@ -106,7 +107,7 @@ export const loadDetailsFromKey = key => (dispatch, getState) => { } }) }) - fetch(`${BSABER_BASE_URL}/wp-json/bsaber-api/songs/${key}/ratings`) + fetch(makeUrl(BSABER_BASE_URL, `/wp-json/bsaber-api/songs/${key}/ratings`)) .then(res => res.json()) .then(bsaberData => { dispatch({ diff --git a/src/actions/modActions.js b/src/actions/modActions.js index 160dee7..43ba3fd 100644 --- a/src/actions/modActions.js +++ b/src/actions/modActions.js @@ -1,7 +1,7 @@ import { SET_MOD_LIST, SET_RESOURCE, SET_LOADING, LOAD_MOD_DETAILS, INSTALL_MOD, SET_SCANNING_FOR_MODS, SET_INSTALLED_MODS, DISPLAY_WARNING, UNINSTALL_MOD, CLEAR_MODS, ADD_TO_QUEUE, UPDATE_PROGRESS, ADD_DEPENDENT, SET_MOD_ACTIVE, ADD_PENDING_MOD, SET_PATCHING, SET_MOD_UPDATE_AVAILABLE, CLEAR_MOD_UPDATES, SET_IGNORE_MOD_UPDATE } from './types' import { MODS_VIEW, MOD_DETAILS } from '../constants/views' import { BEATMODS_BASE_URL } from '../constants/urls' - +import { makeUrl } from '../utilities' import { BEATMODS, LIBRARY } from '../constants/resources' import modIcon from '../assets/dark/mod.png' @@ -28,7 +28,7 @@ export const fetchApprovedMods = () => (dispatch, getState) => { type: SET_LOADING, payload: true }) - fetch(`${BEATMODS_BASE_URL}/api/v1/mod?status=approved&gameVersion=${getState().settings.gameVersion}`) + fetch(makeUrl(BEATMODS_BASE_URL, `/api/v1/mod?status=approved&gameVersion=${getState().settings.gameVersion}`)) .then(res => res.json()) .then(beatModsResponse => { dispatch({ @@ -55,7 +55,7 @@ export const fetchRecommendedMods = () => (dispatch, getState) => { let recommendedMods = ['CameraPlus', 'YUR Fit Calorie Tracker', 'SyncSaber', 'Custom Sabers', 'Custom Platforms', 'Custom Avatars', 'BeatSaberTweaks', 'PracticePlugin', 'Counters+'] let mods = [] for(let i = 0; i < recommendedMods.length; i++) { - fetch(`${BEATMODS_BASE_URL}/api/v1/mod?name=${encodeURIComponent(recommendedMods[i])}&gameVersion=${getState().settings.gameVersion}`) + fetch(makeUrl(BEATMODS_BASE_URL, `/api/v1/mod?name=${encodeURIComponent(recommendedMods[i])}&gameVersion=${getState().settings.gameVersion}`)) .then(res => res.json()) .then(beatModsResponse => { if(beatModsResponse.length === 0) { recommendedMods.splice(i, 1); return } @@ -100,7 +100,7 @@ export const fetchModCategory = category => (dispatch, getState) => { type: SET_LOADING, payload: true }) - fetch(`${BEATMODS_BASE_URL}/api/v1/mod?category=${ category }&status=approved&gameVersion=${getState().settings.gameVersion}`) + fetch(makeUrl(BEATMODS_BASE_URL, `/api/v1/mod?category=${ category }&status=approved&gameVersion=${getState().settings.gameVersion}`)) .then(res => res.json()) .then(beatModsResponse => { dispatch({ @@ -124,7 +124,7 @@ export const fetchLocalMods = () => (dispatch, getState) => { type: SET_LOADING, payload: true }) - fetch(`${BEATMODS_BASE_URL}/api/v1/mod?status=approved&status=inactive`) + fetch(makeUrl(BEATMODS_BASE_URL, `/api/v1/mod?status=approved&status=inactive`)) .then(res => res.json()) .then(beatModsResponse => { let installedMods = getState().mods.installedMods @@ -162,7 +162,7 @@ export const fetchActivatedMods = () => (dispatch, getState) => { type: SET_LOADING, payload: true }) - fetch(`${BEATMODS_BASE_URL}/api/v1/mod?status=approved&status=inactive`) + fetch(makeUrl(BEATMODS_BASE_URL, `/api/v1/mod?status=approved&status=inactive`)) .then(res => res.json()) .then(beatModsResponse => { let activatedMods = getState().mods.installedMods.filter(mod => mod.active === true) @@ -196,7 +196,7 @@ export const loadModDetails = modId => (dispatch, getState) => { type: SET_LOADING, payload: true }) - fetch(`${BEATMODS_BASE_URL}/api/v1/mod`) + fetch(makeUrl(BEATMODS_BASE_URL, '/api/v1/mod')) .then(res => res.json()) .then(beatModsResponse => { dispatch({ @@ -234,7 +234,7 @@ export const installMod = (modName, version, dependencyOf = '') => (dispatch, ge } return } - fetch(`${BEATMODS_BASE_URL}/api/v1/mod?status=approved&status=inactivename=${ encodeURIComponent(modName) }&gameVersion=${ getState().settings.gameVersion }`) + fetch(makeUrl(BEATMODS_BASE_URL, `/api/v1/mod?status=approved&status=inactivename=${ encodeURIComponent(modName) }&gameVersion=${ getState().settings.gameVersion }`)) .then(res => res.json()) .then(beatModsResponse => { let latestVersion = '0.0.0' @@ -285,13 +285,13 @@ export const installMod = (modName, version, dependencyOf = '') => (dispatch, ge } else { zip.extractAllTo(path.join(getState().settings.installationDirectory, 'IPA', 'Pending')) } - + let entries = zip.getEntries() let files = [] for(let i = 0; i < entries.length; i++) { files.push(entries[i].entryName) } - + if(modName === 'BSIPA') { execFile(path.join(getState().settings.installationDirectory, 'IPA.exe'), ['-n'], { cwd: getState().settings.installationDirectory }) dispatch({ @@ -332,13 +332,13 @@ export const installMod = (modName, version, dependencyOf = '') => (dispatch, ge let zip = new AdmZip(data) zip.extractAllTo(getState().settings.installationDirectory) - + let entries = zip.getEntries() let files = [] for(let i = 0; i < entries.length; i++) { files.push(entries[i].entryName) } - + dispatch({ type: INSTALL_MOD, payload: { @@ -518,7 +518,7 @@ export const checkInstalledMods = () => (dispatch, getState) => { let md5sum = crypto.createHash('md5') md5sum.update(data) let hash = md5sum.digest('hex') - fetch(`${BEATMODS_BASE_URL}/api/v1/mod?hash=${hash}`) + fetch(makeUrl(BEATMODS_BASE_URL, `/api/v1/mod?hash=${hash}`)) .then(res => res.json()) .then(beatModsResponse => { if(beatModsResponse.length > 0) { @@ -573,7 +573,7 @@ export const checkInstalledMods = () => (dispatch, getState) => { let md5sum = crypto.createHash('md5') md5sum.update(data) let hash = md5sum.digest('hex') - fetch(`${BEATMODS_BASE_URL}/api/v1/mod?hash=${hash}`) + fetch(makeUrl(BEATMODS_BASE_URL, `/api/v1/mod?hash=${hash}`)) .then(res => res.json()) .then(beatModsResponse => { if(beatModsResponse.length > 0) { @@ -672,7 +672,7 @@ export const checkModsForUpdates = () => (dispatch, getState) => { }) let installedMods = getState().mods.installedMods for(let m = 0; m < installedMods.length; m++) { - fetch(`${BEATMODS_BASE_URL}/api/v1/mod?status=approved&name=${ installedMods[m].name }&gameVersion=${ getState().settings.gameVersion }`) + fetch(makeUrl(BEATMODS_BASE_URL, `/api/v1/mod?status=approved&name=${ installedMods[m].name }&gameVersion=${ getState().settings.gameVersion }`)) .then(res => res.json()) .then(beatModsResponse => { if(beatModsResponse.length === 0) return @@ -732,7 +732,7 @@ export const gamePatchedWith = () => (dispatch, getState) => { installationType = 'IPA' dispatch({ type: 'DISPLAY_WARNING', - payload: { + payload: { text: `Your game is patched with IPA. It is reccommeded that you upgrade to BSIPA to maintain compatability with future mods. To upgrade, reinstall Beat Saber and download any mod from BeatDrop.`, color: 'gold' diff --git a/src/actions/playlistsActions.js b/src/actions/playlistsActions.js index 368bf24..0fda1ea 100644 --- a/src/actions/playlistsActions.js +++ b/src/actions/playlistsActions.js @@ -1,6 +1,7 @@ import { FETCH_LOCAL_PLAYLISTS, LOAD_NEW_PLAYLIST_IMAGE, SET_NEW_PLAYLIST_OPEN, SET_PLAYLIST_PICKER_OPEN, CLEAR_PLAYLIST_DIALOG, LOAD_PLAYLIST_DETAILS, LOAD_PLAYLIST_SONGS, CLEAR_PLAYLIST_DETAILS, SET_PLAYLIST_EDITING, SET_LOADING, DISPLAY_WARNING } from './types' import { PLAYLIST_LIST, PLAYLIST_DETAILS } from '../constants/views' import { BEATSAVER_BASE_URL } from '../constants/urls' +import { makeUrl } from '../utilities' import { defaultPlaylistIcon } from '../b64Assets' import { hashAndWriteToMetadata } from './queueActions' import { setView } from './viewActions' @@ -21,7 +22,7 @@ export const fetchLocalPlaylists = (doSetView) => (dispatch, getState) => { } let playlists = [] fs.access(path.join(state.settings.installationDirectory, 'Playlists'), (err) => { - if(err) { + if(err) { fs.mkdirSync(path.join(state.settings.installationDirectory, 'Playlists')) } fs.readdir(path.join(state.settings.installationDirectory, 'Playlists'), (err, files) => { @@ -197,7 +198,7 @@ export const loadPlaylistDetails = playlistFile => (dispatch, getState) => { }) }) } else { - fetch(`${BEATSAVER_BASE_URL}/api/maps/by-hash/${playlist.songs[i].hash}`) + fetch(makeUrl(BEATSAVER_BASE_URL, `/api/maps/by-hash/${playlist.songs[i].hash}`)) .then(res => res.json()) .then(song => { song.coverURL = `https://beatsaver.com/${song.coverURL}` @@ -214,7 +215,7 @@ export const loadPlaylistDetails = playlistFile => (dispatch, getState) => { }) } } else { - fetch(`${BEATSAVER_BASE_URL}/api/maps/detail/${playlist.songs[i].key}`) + fetch(makeUrl(BEATSAVER_BASE_URL, `/api/maps/detail/${playlist.songs[i].key}`)) .then(res => res.json()) .then(details => { details.coverURL = `${BEATSAVER_BASE_URL}/${details.coverURL}` @@ -331,7 +332,7 @@ export const addSongToPlaylist = (song, playlistFile) => (dispatch, getState) => }) }) } - + fs.writeFile(playlistFile, JSON.stringify(playlist), 'UTF8', (err) => { if(err) { dispatch({ diff --git a/src/actions/queueActions.js b/src/actions/queueActions.js index 9e03d45..d83aad4 100644 --- a/src/actions/queueActions.js +++ b/src/actions/queueActions.js @@ -1,6 +1,7 @@ import { ADD_TO_QUEUE, CLEAR_QUEUE, UPDATE_PROGRESS, SET_DOWNLOADED_SONGS, SET_DOWNLOADING_COUNT, SET_WAIT_LIST, DISPLAY_WARNING, SET_SCANNING_FOR_SONGS, SET_DISCOVERED_FILES, SET_PROCESSED_FILES } from './types' import { SONG_LIST } from '../constants/views' import { BEATSAVER_BASE_URL } from '../constants/urls' +import { makeUrl } from '../utilities' import { isModInstalled, installEssentialMods } from './modActions' import { setView } from './viewActions' @@ -20,7 +21,7 @@ export const downloadSong = (identity) => (dispatch, getState) => { if(!isModInstalled('SongLoader')(dispatch, getState)) installEssentialMods()(dispatch, getState) let hash = identity if(identity) { - fetch(`${BEATSAVER_BASE_URL}/api/maps/by-hash/${hash}`) + fetch(makeUrl(BEATSAVER_BASE_URL, `/api/maps/by-hash/${hash}`)) .then(res => res.json()) .then(song => { hash = song.hash @@ -40,14 +41,14 @@ export const downloadSong = (identity) => (dispatch, getState) => { setTimeout(() => { document.getElementById('queue-button').classList.remove('notify') }, 1000) - fetch(`${BEATSAVER_BASE_URL}/api/maps/by-hash/${hash}`) + fetch(makeUrl(BEATSAVER_BASE_URL, `/api/maps/by-hash/${hash}`)) .then(res => res.json()) .then(song => { let utc = Date.now() if(song) { dispatch({ type: ADD_TO_QUEUE, - payload: { + payload: { utc, hash: song.hash, image: `${BEATSAVER_BASE_URL}${ song.coverURL }`, @@ -238,13 +239,13 @@ export const downloadSong = (identity) => (dispatch, getState) => { setTimeout(() => { document.getElementById('queue-button').classList.remove('notify') }, 1000) - fetch(`${BEATSAVER_BASE_URL}/api/maps/by-hash/${hash}`) + fetch(makeUrl(BEATSAVER_BASE_URL, `/api/maps/by-hash/${hash}`)) .then(res => res.json()) .then(song => { let utc = Date.now() dispatch({ type: ADD_TO_QUEUE, - payload: { + payload: { utc, hash: song.hash, image: `${BEATSAVER_BASE_URL}${ song.coverURL }`, diff --git a/src/actions/searchActions.js b/src/actions/searchActions.js index e375587..c9d1808 100644 --- a/src/actions/searchActions.js +++ b/src/actions/searchActions.js @@ -1,5 +1,6 @@ import { SET_SEARCH_SOURCES, SUBMIT_SEARCH, SET_LOADING } from './types' import { BEATSAVER_BASE_URL } from '../constants/urls' +import { makeUrl } from '../utilities' const { remote } = window.require('electron') const fs = remote.require('fs') @@ -49,7 +50,7 @@ export const submitSearch = keywords => (dispatch, getState) => { localResultsReady = true // BeatSaver Search - fetch(`${BEATSAVER_BASE_URL}/api/search/text/all?q=` + encodeURIComponent(keywords.replace('/', '\\'))) + fetch(makeUrl(BEATSAVER_BASE_URL, `/api/search/text/all?q=${encodeURIComponent(keywords.replace('/', '\\'))}`)) .then(res => res.json()) .then(data => { beatSaverSongs = data.docs @@ -66,10 +67,10 @@ export const submitSearch = keywords => (dispatch, getState) => { } beatSaverResultsReady = true }) - + // BeatSaver ID Search if(isId) { - fetch(`${BEATSAVER_BASE_URL}/api/maps/detail/` + keywords) + fetch(makeUrl(BEATSAVER_BASE_URL, `/api/maps/detail/${keywords}`)) .then(res => { if(res.status !== 200) { beatSaverIdResultsReady = true; return } return res.json() }) .then(data => { if(!data) { beatSaverIdResultsReady = true; return } diff --git a/src/actions/songListActions.js b/src/actions/songListActions.js index cb39a52..bb38736 100644 --- a/src/actions/songListActions.js +++ b/src/actions/songListActions.js @@ -2,6 +2,7 @@ import { FETCH_NEW, FETCH_TOP_DOWNLOADS, FETCH_TOP_FINISHED, FETCH_LOCAL_SONGS, import { SONG_LIST } from '../constants/views' import { BEATSAVER, LIBRARY } from '../constants/resources' import { BEATSAVER_BASE_URL, BSABER_BASE_URL } from '../constants/urls' +import { makeUrl } from '../utilities' import { hashAndWriteToMetadata } from './queueActions' import { setView } from './viewActions' @@ -29,7 +30,7 @@ export const fetchNew = () => (dispatch, getState) => { type: SET_RESOURCE, payload: BEATSAVER.NEW_SONGS }) - fetch(`${BEATSAVER_BASE_URL}api/maps/latest`) + fetch(makeUrl(BEATSAVER_BASE_URL, '/api/maps/latest')) .then(res => res.json()) .then(data => { console.log(data) @@ -43,7 +44,7 @@ export const fetchNew = () => (dispatch, getState) => { }) console.log(data); for(let i = 0; i < data.docs.length; i++) { - fetch(`${BSABER_BASE_URL}/wp-json/bsaber-api/songs/${data.docs[i].key}/ratings`) + fetch(makeUrl(BSABER_BASE_URL, `/wp-json/bsaber-api/songs/${data.docs[i].key}/ratings`)) .then(res => res.json()) .then(bsaberData => { dispatch({ @@ -75,7 +76,7 @@ export const fetchTopDownloads = () => (dispatch, getState) => { type: SET_RESOURCE, payload: BEATSAVER.TOP_DOWNLOADED_SONGS }) - fetch(`${BEATSAVER_BASE_URL}/api/maps/downloads`) + fetch(makeUrl(BEATSAVER_BASE_URL, '/api/maps/downloads')) .then(res => res.json()) .then(data => { dispatch({ @@ -86,8 +87,8 @@ export const fetchTopDownloads = () => (dispatch, getState) => { type: SET_LOADING, payload: false }) - for(let i = 0; i < data.songs.length; i++) { - fetch(`${BSABER_BASE_URL}/wp-json/bsaber-api/songs/${data.docs[i].key}/ratings`) + for(let i = 0; i < data.docs.length; i++) { + fetch(makeUrl(BSABER_BASE_URL, `/wp-json/bsaber-api/songs/${data.docs[i].key}/ratings`)) .then(res => res.json()) .then(bsaberData => { dispatch({ @@ -119,7 +120,7 @@ export const fetchTopFinished = () => (dispatch, getState) => { type: SET_RESOURCE, payload: BEATSAVER.TOP_FINISHED_SONGS }) - fetch(`${BEATSAVER_BASE_URL}/api/maps/plays`) + fetch(makeUrl(BEATSAVER_BASE_URL, '/api/maps/plays')) .then(res => res.json()) .then(data => { dispatch({ @@ -131,7 +132,7 @@ export const fetchTopFinished = () => (dispatch, getState) => { payload: false }) for(let i = 0; i < data.docs.length; i++) { - fetch(`${BSABER_BASE_URL}/wp-json/bsaber-api/songs/${data.docs[i].key}/ratings`) + fetch(makeUrl(BSABER_BASE_URL, `/wp-json/bsaber-api/songs/${data.docs[i].key}/ratings`)) .then(res => res.json()) .then(bsaberData => { dispatch({ @@ -216,7 +217,7 @@ export const loadMore = () => (dispatch, getState) => { payload: true }) let state = getState() - fetch(resourceUrl[state.resource] + '/' + state.songs.songs.length) + fetch(makeUrl(resourceUrl[state.resource], `/${state.songs.nextFetch}`)) .then(res => { return res.json() }) @@ -231,7 +232,7 @@ export const loadMore = () => (dispatch, getState) => { }) console.log(data) for(let i = state.songs.songs.length; i < state.songs.songs.length + data.docs.length; i++) { - fetch(`${BSABER_BASE_URL}/wp-json/bsaber-api/songs/${data.docs[i - state.songs.songs.length].key}/ratings`) + fetch(makeUrl(BSABER_BASE_URL, `/wp-json/bsaber-api/songs/${data.docs[i - state.songs.songs.length].key}/ratings`)) .then(res => res.json()) .then(bsaberData => { dispatch({ @@ -251,7 +252,7 @@ export const loadMore = () => (dispatch, getState) => { dispatch({ type: DISPLAY_WARNING, payload: { - text: 'There was error loading more songs. Check your connection to the internet and try again.' + text: 'There was an error loading more songs. Check your connection to the internet and try again.' } }) }) diff --git a/src/components/CoverGrid.js b/src/components/CoverGrid.js index d77f561..5d3b103 100644 --- a/src/components/CoverGrid.js +++ b/src/components/CoverGrid.js @@ -18,8 +18,6 @@ import { displayWarning } from '../actions/warningActions' import { ContextMenu, MenuItem, ContextMenuTrigger } from "react-contextmenu"; -import { makeRenderKey } from '../utilities' - const { clipboard, shell } = window.require('electron') class CoverGrid extends Component { @@ -36,7 +34,7 @@ class CoverGrid extends Component { document.getElementById('cover-grid-container').addEventListener('scroll', this.onScroll.bind(this)) document.getElementById('cover-grid-container').scrollTop = this.props.scrollTop } - + componentWillUnmount() { document.getElementById('cover-grid-container').removeEventListener('scroll', this.onScroll) } @@ -61,38 +59,29 @@ class CoverGrid extends Component { }) : this.props.songs.songs.map((song, i) => { - let songTags = [ - { - boolean: true, - tag: song.hash || song.hashMd5 - }, - { - boolean: !!song.file || this.props.songs.downloadedSongs.some(dsong => dsong.hash === (song.hash || song.hashMd5)), - tag: '.downloaded' - } - ] + let hash = song.hash || song.hashMd5 return ( - + - - {e.stopPropagation(); (!!song.file || this.props.songs.downloadedSongs.some(dsong => dsong.hash === (song.hash || song.hashMd5))) ? this.props.deleteSong(song.file || song.hash || song.hashMd5) : this.props.downloadSong(song.hash || song.hashMd5)} }> - {`${(!!song.file || this.props.songs.downloadedSongs.some(dsong => dsong.hash === (song.hash || song.hashMd5))) ? 'Delete' : 'Download'} ${song.songName}`} + + {e.stopPropagation(); (!!song.file || this.props.songs.downloadedSongs.some(dsong => dsong.hash === (hash))) ? this.props.deleteSong(song.file || hash) : this.props.downloadSong(hash)} }> + {`${(!!song.file || this.props.songs.downloadedSongs.some(dsong => dsong.hash === (hash))) ? 'Delete' : 'Download'} ${song.songName}`} {e.stopPropagation(); this.setState({ song }); this.props.setPlaylistPickerOpen(true)} }> Add to Playlist - {e.stopPropagation(); if(song.hash || song.hashMd5 || song.key) { clipboard.writeText(`beatdrop://songs/details/${song.hash || song.hashMd5 || song.key}`); this.props.displayWarning({ timeout: 5000, color:'lightgreen', text: `Sharable Link for ${song.songName} copied to clipboard!` })} else { this.props.displayWarning({ text: `Failed to identify song. Song may have been downloaded externally. Songs will now be scanned. Please try again when scanning is finished.` }); this.props.checkDownloadedSongs(); }} }>Share + {e.stopPropagation(); if(hash || song.key) { clipboard.writeText(`beatdrop://songs/details/${hash || song.key}`); this.props.displayWarning({ timeout: 5000, color:'lightgreen', text: `Sharable Link for ${song.songName} copied to clipboard!` })} else { this.props.displayWarning({ text: `Failed to identify song. Song may have been downloaded externally. Songs will now be scanned. Please try again when scanning is finished.` }); this.props.checkDownloadedSongs(); }} }>Share {(!!song.id ? {e.stopPropagation(); shell.openExternal(`https://www.bsaber.com/songs/${song.id}`)} }>View on BeastSaber : null)} diff --git a/src/components/CoverGridItem.js b/src/components/CoverGridItem.js index 79972fe..074d5ca 100644 --- a/src/components/CoverGridItem.js +++ b/src/components/CoverGridItem.js @@ -94,7 +94,7 @@ componentWillReceiveProps(props) { if(this.props.loading) { return (
- { + {
) } else { diff --git a/src/components/DownloadQueue.js b/src/components/DownloadQueue.js index 357b4e3..a50fc60 100644 --- a/src/components/DownloadQueue.js +++ b/src/components/DownloadQueue.js @@ -9,35 +9,35 @@ import { clearQueue } from '../actions/queueActions' class DownloadQueue extends Component { render() { - if(this.props.isOpen) { - return ( -
-
Download Queue
- -
- ) - } else { + const shouldHide = !this.props.items || this.props.items.length === 0 + + if (shouldHide) { return null } + + return ( +
+
Download Queue
+ +
+ ) } } DownloadQueue.propTypes = { items: PropTypes.array.isRequired, - isOpen: PropTypes.bool.isRequired, theme: PropTypes.string.isRequired, clearQueue: PropTypes.func.isRequired } let mapStateToProps = (state) => ({ items: state.queue.items, - isOpen: state.queue.isOpen, theme: state.settings.theme }) diff --git a/src/components/LoadMore.js b/src/components/LoadMore.js index c1c3ce5..d598470 100644 --- a/src/components/LoadMore.js +++ b/src/components/LoadMore.js @@ -32,19 +32,18 @@ class LoadMore extends Component { ) } - + } } LoadMore.propTypes = { loadingMore: PropTypes.bool.isRequired, - source: PropTypes.object.isRequired, - loadMore: PropTypes.func.isRequired + loadMore: PropTypes.func.isRequired, + songs: PropTypes.object.isRequired } const mapStateToProps = (state) => ({ loadingMore: state.loadingMore, - source: state.source, songs: state.songs }) diff --git a/src/components/ModsView.js b/src/components/ModsView.js index 9ab7ed1..c49790a 100644 --- a/src/components/ModsView.js +++ b/src/components/ModsView.js @@ -2,13 +2,14 @@ import React, { Component, Fragment } from 'react' import '../css/ModsView.scss' import { connect } from 'react-redux' +import { BEATMODS_BASE_URL } from '../constants/urls' import { BEATMODS, LIBRARY } from '../constants/resources'; +import { makeUrl } from '../utilities' import { loadModDetails, installMod, uninstallMod, fetchModCategory, deactivateMod, activateMod } from '../actions/modActions' import { displayWarning } from '../actions/warningActions' import { ContextMenuTrigger, MenuItem, ContextMenu } from 'react-contextmenu'; -import { makeRenderKey } from '../utilities' import LibraryIndicator from './LibraryIndicator'; import DeactivatedIndicator from './DeactivatedIndicator'; import SortBar from './SortBar'; @@ -19,7 +20,7 @@ class ModsView extends Component { Catergories(props) { return (