Splitting out helpers into separate files

This commit is contained in:
James Barnsley
2020-03-03 16:39:37 +13:00
parent 57dd18e870
commit 5a1f08fdf0
105 changed files with 5456 additions and 5574 deletions

View File

@ -15,19 +15,20 @@ import Dater from '../components/Dater';
import LazyLoadListener from '../components/LazyLoadListener';
import ContextMenuTrigger from '../components/ContextMenuTrigger';
import Icon from '../components/Icon';
import * as helpers from '../helpers';
import * as coreActions from '../services/core/actions';
import * as uiActions from '../services/ui/actions';
import * as mopidyActions from '../services/mopidy/actions';
import * as spotifyActions from '../services/spotify/actions';
import * as lastfmActions from '../services/lastfm/actions';
import {
uriSource,
getFromUri,
isLoading,
sourceIcon,
} from '../util/helpers';
import { collate } from '../util/format';
export class Album extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.setWindowTitle();
this.props.coreActions.loadAlbum(this.props.uri);
@ -57,7 +58,7 @@ export class Album extends React.Component {
// if mopidy has just connected AND we're a local album, go get
} else if (!this.props.mopidy_connected && nextProps.mopidy_connected) {
if (helpers.uriSource(nextProps.uri) != 'spotify') {
if (uriSource(nextProps.uri) != 'spotify') {
this.props.coreActions.loadAlbum(nextProps.uri);
}
}
@ -135,7 +136,7 @@ export class Album extends React.Component {
}
inLibrary() {
const library = `${helpers.uriSource(this.props.uri)}_library_albums`;
const library = `${uriSource(this.props.uri)}_library_albums`;
return (
this.props[library] && this.props[library].indexOf(this.props.uri) > -1
);
@ -144,8 +145,8 @@ export class Album extends React.Component {
render() {
if (!this.props.album) {
if (
helpers.isLoading(this.props.load_queue, [
`spotify_albums/${helpers.getFromUri('albumid', this.props.uri)}`,
isLoading(this.props.load_queue, [
`spotify_albums/${getFromUri('albumid', this.props.uri)}`,
])
) {
return <Loader body loading />;
@ -161,7 +162,7 @@ export class Album extends React.Component {
);
}
const album = helpers.collate(this.props.album, {
const album = collate(this.props.album, {
tracks: this.props.tracks,
artists: this.props.artists,
});
@ -190,7 +191,7 @@ export class Album extends React.Component {
<ul className="details">
{!this.props.slim_mode ? (
<li className="source">
<Icon type="fontawesome" name={helpers.sourceIcon(album.uri)} />
<Icon type="fontawesome" name={sourceIcon(album.uri)} />
</li>
) : null}
{album.artists && album.artists.length > 0 ? (
@ -236,7 +237,7 @@ listeners
<button className="button button--primary" onClick={(e) => this.play()}>
Play
</button>
{helpers.uriSource(this.props.uri) == 'spotify' ? (
{uriSource(this.props.uri) == 'spotify' ? (
<FollowButton
className="secondary"
uri={this.props.uri}

View File

@ -3,7 +3,6 @@ import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Route, Switch } from 'react-router-dom';
import ErrorMessage from '../components/ErrorMessage';
import Link from '../components/Link';
import LazyLoadListener from '../components/LazyLoadListener';
@ -18,20 +17,23 @@ import ContextMenuTrigger from '../components/ContextMenuTrigger';
import DropdownField from '../components/Fields/DropdownField';
import Icon from '../components/Icon';
import Loader from '../components/Loader';
import * as helpers from '../helpers';
import * as coreActions from '../services/core/actions';
import * as uiActions from '../services/ui/actions';
import * as mopidyActions from '../services/mopidy/actions';
import * as pusherActions from '../services/pusher/actions';
import * as lastfmActions from '../services/lastfm/actions';
import * as spotifyActions from '../services/spotify/actions';
import {
uriSource,
getFromUri,
isLoading,
sourceIcon,
titleCase,
} from '../util/helpers';
import { collate } from '../util/format';
import { sortItems, applyFilter } from '../util/arrays';
class Artist extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.setWindowTitle();
this.props.coreActions.loadArtist(this.props.uri);
@ -41,7 +43,7 @@ class Artist extends React.Component {
if (nextProps.uri != this.props.uri) {
this.props.coreActions.loadArtist(nextProps.uri);
} else if (!this.props.mopidy_connected && nextProps.mopidy_connected) {
if (helpers.uriSource(this.props.uri) != 'spotify') {
if (uriSource(this.props.uri) != 'spotify') {
this.props.coreActions.loadArtist(nextProps.uri);
}
}
@ -85,7 +87,7 @@ class Artist extends React.Component {
}
inLibrary() {
const library = `${helpers.uriSource(this.props.uri)}_library_artists`;
const library = `${uriSource(this.props.uri)}_library_artists`;
return (this.props[library] && this.props[library].indexOf(this.props.uri) > -1);
}
@ -107,7 +109,7 @@ class Artist extends React.Component {
}
renderOverview() {
const artist = helpers.collate(
const artist = collate(
this.props.artist,
{
artists: this.props.artists,
@ -117,11 +119,11 @@ class Artist extends React.Component {
);
if (this.props.sort && artist.albums) {
artist.albums = helpers.sortItems(artist.albums, this.props.sort, this.props.sort_reverse);
artist.albums = sortItems(artist.albums, this.props.sort, this.props.sort_reverse);
}
if (this.props.filter && artist.albums) {
artist.albums = helpers.applyFilter('type', this.props.filter, artist.albums);
artist.albums = applyFilter('type', this.props.filter, artist.albums);
}
const sort_options = [
@ -234,7 +236,7 @@ class Artist extends React.Component {
}
renderTracks() {
const artist = helpers.collate(
const artist = collate(
this.props.artist,
{
artists: this.props.artists,
@ -259,7 +261,7 @@ class Artist extends React.Component {
}
renderRelatedArtists() {
const artist = helpers.collate(
const artist = collate(
this.props.artist,
{
artists: this.props.artists,
@ -276,7 +278,7 @@ class Artist extends React.Component {
}
renderAbout() {
const artist = helpers.collate(
const artist = collate(
this.props.artist,
{
artists: this.props.artists,
@ -305,8 +307,8 @@ class Artist extends React.Component {
{thumbnails}
<div className="tile">
<span className="content">
<Icon type="fontawesome" name={helpers.sourceIcon(artist.uri)} />
{`${helpers.titleCase(helpers.uriSource(artist.uri))} artist`}
<Icon type="fontawesome" name={sourceIcon(artist.uri)} />
{`${titleCase(uriSource(artist.uri))} artist`}
</span>
</div>
{artist.followers && (
@ -358,10 +360,10 @@ class Artist extends React.Component {
}
render() {
const scheme = helpers.uriSource(this.props.uri);
const scheme = uriSource(this.props.uri);
if (!this.props.artist) {
if (helpers.isLoading(this.props.load_queue, [`spotify_artists/${helpers.getFromUri('artistid', this.props.uri)}`, 'lastfm_method=artist.getInfo'])) {
if (isLoading(this.props.load_queue, [`spotify_artists/${getFromUri('artistid', this.props.uri)}`, 'lastfm_method=artist.getInfo'])) {
return <Loader body loading />;
}
return (

View File

@ -1,14 +1,9 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Header from '../components/Header';
import Thumbnail from '../components/Thumbnail';
import Icon from '../components/Icon';
import Link from '../components/Link';
import * as uiActions from '../services/ui/actions';
import * as pusherActions from '../services/pusher/actions';
import * as mopidyActions from '../services/mopidy/actions';

View File

@ -3,7 +3,6 @@ import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import ErrorMessage from '../components/ErrorMessage';
import Link from '../components/Link';
import TrackList from '../components/TrackList';
@ -17,12 +16,17 @@ import Loader from '../components/Loader';
import ContextMenuTrigger from '../components/ContextMenuTrigger';
import URILink from '../components/URILink';
import Icon from '../components/Icon';
import * as helpers from '../helpers';
import * as coreActions from '../services/core/actions';
import * as uiActions from '../services/ui/actions';
import * as mopidyActions from '../services/mopidy/actions';
import * as spotifyActions from '../services/spotify/actions';
import {
uriSource,
getFromUri,
isLoading,
sourceIcon,
} from '../util/helpers';
import { collate } from '../util/format';
class Playlist extends React.Component {
constructor(props) {
@ -52,7 +56,7 @@ class Playlist extends React.Component {
if (nextProps.uri != this.props.uri) {
this.props.coreActions.loadPlaylist(nextProps.uri);
} else if (!this.props.mopidy_connected && nextProps.mopidy_connected) {
if (helpers.uriSource(this.props.uri) != 'spotify') {
if (uriSource(this.props.uri) != 'spotify') {
this.props.coreActions.loadPlaylist(nextProps.uri);
}
}
@ -128,12 +132,12 @@ class Playlist extends React.Component {
}
inLibrary() {
const library = `${helpers.uriSource(this.props.uri)}_library_playlists`;
const library = `${uriSource(this.props.uri)}_library_playlists`;
return (this.props[library] && this.props[library].indexOf(this.props.uri) > -1);
}
renderActions() {
switch (helpers.uriSource(this.props.uri)) {
switch (uriSource(this.props.uri)) {
case 'm3u':
return (
<div className="actions">
@ -172,10 +176,10 @@ class Playlist extends React.Component {
}
render() {
const playlist_id = helpers.getFromUri('playlistid', this.props.uri);
const playlist_id = getFromUri('playlistid', this.props.uri);
if (!this.props.playlist) {
if (helpers.isLoading(this.props.load_queue, [`spotify_playlists/${playlist_id}?`])) {
if (isLoading(this.props.load_queue, [`spotify_playlists/${playlist_id}?`])) {
return <Loader body loading />
}
return (
@ -189,7 +193,7 @@ Could not find playlist with URI "
);
}
const playlist = helpers.collate(this.props.playlist, { tracks: this.props.tracks, users: this.props.users });
const playlist = collate(this.props.playlist, { tracks: this.props.tracks, users: this.props.users });
let context = 'playlist';
if (playlist.can_edit) {
@ -216,8 +220,8 @@ Could not find playlist with URI "
{playlist.description ? <h2 className="description" dangerouslySetInnerHTML={{ __html: playlist.description }} /> : null }
<ul className="details">
{!this.props.slim_mode ? <li className="source"><Icon type="fontawesome" name={helpers.sourceIcon(playlist.uri)} /></li> : null }
{playlist.user_uri ? <li><URILink type="user" uri={playlist.user_uri}>{playlist.user ? playlist.user.name : helpers.getFromUri('userid', playlist.user_uri)}</URILink></li> : null }
{!this.props.slim_mode ? <li className="source"><Icon type="fontawesome" name={sourceIcon(playlist.uri)} /></li> : null }
{playlist.user_uri ? <li><URILink type="user" uri={playlist.user_uri}>{playlist.user ? playlist.user.name : getFromUri('userid', playlist.user_uri)}</URILink></li> : null }
<li>
{playlist.tracks_total ? playlist.tracks_total : '0'}
{' '}

View File

@ -1,7 +1,6 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Link from '../components/Link';
import Icon from '../components/Icon';
import Parallax from '../components/Parallax';
@ -12,13 +11,15 @@ import Thumbnail from '../components/Thumbnail';
import Header from '../components/Header';
import URILink from '../components/URILink';
import LazyLoadListener from '../components/LazyLoadListener';
import * as helpers from '../helpers';
import * as coreActions from '../services/core/actions';
import * as uiActions from '../services/ui/actions';
import * as pusherActions from '../services/pusher/actions';
import * as spotifyActions from '../services/spotify/actions';
import * as mopidyActions from '../services/mopidy/actions';
import {
getFromUri,
uriType,
} from '../util/helpers';
class Queue extends React.Component {
constructor(props) {
@ -51,7 +52,7 @@ class Queue extends React.Component {
const { coreActions, added_from_uri } = this.props;
if (next_added_from_uri && next_added_from_uri !== added_from_uri) {
const item_type = helpers.uriType(next_added_from_uri);
const item_type = uriType(next_added_from_uri);
switch (item_type) {
case 'album':
coreActions.loadAlbum(next_added_from_uri);
@ -138,16 +139,16 @@ class Queue extends React.Component {
const { added_from_uri } = this.props;
if (!added_from_uri) return null;
const uri_type = helpers.uriType(added_from_uri);
const uri_type = uriType(added_from_uri);
const items = [];
// Radio nests it's seed URIs in an encoded URI format
switch (uri_type){
case 'radio':
const radio_seeds = helpers.getFromUri('seeds', added_from_uri);
const radio_seeds = getFromUri('seeds', added_from_uri);
for (let seed of radio_seeds) {
let item_type = helpers.uriType(seed);
let item_type = uriType(seed);
let item_library = this.props[`${item_type}s`];
if (item_library && item_library[seed]) {
items.push(item_library[seed]);
@ -158,7 +159,7 @@ class Queue extends React.Component {
case 'search':
items.push({
uri: added_from_uri,
name: `"${helpers.getFromUri('searchterm', added_from_uri)}" search`,
name: `"${getFromUri('searchterm', added_from_uri)}" search`,
})
break;
@ -182,7 +183,7 @@ class Queue extends React.Component {
<Thumbnail
images={items[0].images}
size="small"
circle={helpers.uriType(items[0].uri) === 'artist'}
circle={uriType(items[0].uri) === 'artist'}
/>
</URILink>
)}

View File

@ -1,23 +1,16 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import TrackList from '../components/TrackList';
import Header from '../components/Header';
import Icon from '../components/Icon';
import * as uiActions from '../services/ui/actions';
import * as pusherActions from '../services/pusher/actions';
import * as spotifyActions from '../services/spotify/actions';
import * as mopidyActions from '../services/mopidy/actions';
class QueueHistory extends React.Component {
constructor(props) {
super(props);
}
class QueueHistory extends React.Component {
componentDidMount() {
this.props.uiActions.setWindowTitle('Queue history');
this.loadHistory();
@ -38,7 +31,7 @@ class QueueHistory extends React.Component {
render() {
const options = (
<a className="button button--no-hover" onClick={(e) => this.props.history.push('/queue')}>
<Icon name="keyboard_backspace" />
<Icon name="keyboard_backspace" />
&nbsp;
Back
</a>
@ -71,7 +64,7 @@ class QueueHistory extends React.Component {
className="queue-history-track-list"
track_context="history"
tracks={tracks}
show_source_icon
show_source_icon
/>
</section>
@ -100,4 +93,4 @@ const mapDispatchToProps = (dispatch) => ({
mopidyActions: bindActionCreators(mopidyActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(QueueHistory);
export default connect(mapStateToProps, mapDispatchToProps)(QueueHistory);

View File

@ -3,8 +3,6 @@ import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Switch, Route } from 'react-router-dom';
import Link from '../components/Link';
import Header from '../components/Header';
import Icon from '../components/Icon';
import DropdownField from '../components/Fields/DropdownField';
@ -15,12 +13,15 @@ import PlaylistGrid from '../components/PlaylistGrid';
import LazyLoadListener from '../components/LazyLoadListener';
import SearchForm from '../components/Fields/SearchForm';
import URILink from '../components/URILink';
import * as helpers from '../helpers';
import * as coreActions from '../services/core/actions';
import * as uiActions from '../services/ui/actions';
import * as mopidyActions from '../services/mopidy/actions';
import * as spotifyActions from '../services/spotify/actions';
import {
titleCase,
getIndexedRecords,
} from '../util/helpers';
import { sortItems } from '../util/arrays';
class Search extends React.Component {
constructor(props) {
@ -329,7 +330,7 @@ class Search extends React.Component {
for (let i = 0; i < this.props.uri_schemes.length; i++) {
provider_options.push({
value: this.props.uri_schemes[i],
label: helpers.titleCase(this.props.uri_schemes[i].replace(':', '').replace('+', ' ')),
label: titleCase(this.props.uri_schemes[i].replace(':', '').replace('+', ' ')),
});
}
const spotify_search_enabled = (this.props.search_settings && this.props.search_settings.spotify);
@ -352,30 +353,30 @@ class Search extends React.Component {
let artists = [];
if (this.props.mopidy_search_results.artists) {
artists = [...artists, ...helpers.getIndexedRecords(this.props.artists, this.props.mopidy_search_results.artists)];
artists = [...artists, ...getIndexedRecords(this.props.artists, this.props.mopidy_search_results.artists)];
}
if (this.props.spotify_search_results.artists) {
artists = [...artists, ...helpers.getIndexedRecords(this.props.artists, this.props.spotify_search_results.artists)];
artists = [...artists, ...getIndexedRecords(this.props.artists, this.props.spotify_search_results.artists)];
}
artists = helpers.sortItems(artists, sort, sort_reverse, sort_map);
artists = sortItems(artists, sort, sort_reverse, sort_map);
let albums = [];
if (this.props.mopidy_search_results.albums) {
albums = [...albums, ...helpers.getIndexedRecords(this.props.albums, this.props.mopidy_search_results.albums)];
albums = [...albums, ...getIndexedRecords(this.props.albums, this.props.mopidy_search_results.albums)];
}
if (this.props.spotify_search_results.albums) {
albums = [...albums, ...helpers.getIndexedRecords(this.props.albums, this.props.spotify_search_results.albums)];
albums = [...albums, ...getIndexedRecords(this.props.albums, this.props.spotify_search_results.albums)];
}
albums = helpers.sortItems(albums, sort, sort_reverse, sort_map);
albums = sortItems(albums, sort, sort_reverse, sort_map);
let playlists = [];
if (this.props.mopidy_search_results.playlists) {
playlists = [...playlists, ...helpers.getIndexedRecords(this.props.playlists, this.props.mopidy_search_results.playlists)];
playlists = [...playlists, ...getIndexedRecords(this.props.playlists, this.props.mopidy_search_results.playlists)];
}
if (this.props.spotify_search_results.playlists) {
playlists = [...playlists, ...helpers.getIndexedRecords(this.props.playlists, this.props.spotify_search_results.playlists)];
playlists = [...playlists, ...getIndexedRecords(this.props.playlists, this.props.spotify_search_results.playlists)];
}
playlists = helpers.sortItems(playlists, sort, sort_reverse, sort_map);
playlists = sortItems(playlists, sort, sort_reverse, sort_map);
let tracks = [];
if (this.props.mopidy_search_results.tracks) {
@ -385,7 +386,7 @@ class Search extends React.Component {
tracks = [...tracks, ...this.props.spotify_search_results.tracks];
}
tracks = helpers.sortItems(tracks, (sort == 'followers' ? 'popularity' : sort), sort_reverse, sort_map);
tracks = sortItems(tracks, (sort == 'followers' ? 'popularity' : sort), sort_reverse, sort_map);
const options = (
<span>

View File

@ -3,7 +3,6 @@ import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Route, Link } from 'react-router-dom';
import ConfirmationButton from '../components/Fields/ConfirmationButton';
import PusherConnectionList from '../components/PusherConnectionList';
import SourcesPriority from '../components/Fields/SourcesPriority';
@ -12,14 +11,13 @@ import TextField from '../components/Fields/TextField';
import Header from '../components/Header';
import Icon from '../components/Icon';
import Services from '../components/Services';
import * as helpers from '../helpers';
import * as coreActions from '../services/core/actions';
import * as uiActions from '../services/ui/actions';
import * as pusherActions from '../services/pusher/actions';
import * as mopidyActions from '../services/mopidy/actions';
import * as lastfmActions from '../services/lastfm/actions';
import * as spotifyActions from '../services/spotify/actions';
import { isHosted } from '../util/helpers';
class Settings extends React.Component {
constructor(props) {
@ -350,7 +348,7 @@ class Settings extends React.Component {
</div>
</div>
{helpers.isHosted() ? null : (
{isHosted() ? null : (
<div className="field checkbox">
<div className="name">Reporting</div>
<div className="input">

View File

@ -2,7 +2,6 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Link from '../components/Link';
import ErrorMessage from '../components/ErrorMessage';
import Header from '../components/Header';
@ -14,20 +13,21 @@ import SelectField from '../components/Fields/SelectField';
import ContextMenuTrigger from '../components/ContextMenuTrigger';
import Icon from '../components/Icon';
import Loader from '../components/Loader';
import * as helpers from '../helpers';
import * as coreActions from '../services/core/actions';
import * as uiActions from '../services/ui/actions';
import * as mopidyActions from '../services/mopidy/actions';
import * as spotifyActions from '../services/spotify/actions';
import * as lastfmActions from '../services/lastfm/actions';
import * as geniusActions from '../services/genius/actions';
import {
isLoading,
getFromUri,
sourceIcon,
uriSource,
uriType,
} from '../util/helpers';
class Track extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.props.coreActions.loadTrack(this.props.uri);
@ -155,7 +155,7 @@ class Track extends React.Component {
}
renderLyrics() {
if (helpers.isLoading(this.props.load_queue, ['genius_'])) {
if (isLoading(this.props.load_queue, ['genius_'])) {
return (
<div className="lyrics">
<Loader body loading />
@ -179,7 +179,7 @@ class Track extends React.Component {
}
render() {
if (helpers.isLoading(this.props.load_queue, [`spotify_track/${helpers.getFromUri('trackid', this.props.uri)}`])) {
if (isLoading(this.props.load_queue, [`spotify_track/${getFromUri('trackid', this.props.uri)}`])) {
return <Loader body loading />
}
@ -226,7 +226,7 @@ class Track extends React.Component {
</h2>
<ul className="details">
{!this.props.slim_mode ? <li className="source"><Icon type="fontawesome" name={helpers.sourceIcon(this.props.uri)} /></li> : null}
{!this.props.slim_mode ? <li className="source"><Icon type="fontawesome" name={sourceIcon(this.props.uri)} /></li> : null}
{track.date ? <li><Dater type="date" data={track.date} /></li> : null}
{track.explicit ? <li><span className="flag flag--dark">EXPLICIT</span></li> : null}
<li>
@ -272,11 +272,11 @@ Want track lyrics? Authorize Genius under
* @return String
* */
const rebuildUri = (uri) => {
const rebuilt_uri = `${helpers.uriSource(uri)}:${helpers.uriType(uri)}:`;
const rebuilt_uri = `${uriSource(uri)}:${uriType(uri)}:`;
// Escape unreserved characters (RFC 3986)
// https://stackoverflow.com/questions/18251399/why-doesnt-encodeuricomponent-encode-single-quotes-apostrophes
let id = helpers.getFromUri('trackid', uri);
let id = getFromUri('trackid', uri);
id = encodeURIComponent(id).replace(/[!'()*]/g, escape);
// Reinstate slashes for the Mopidy-Local structure

View File

@ -2,7 +2,6 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ErrorMessage from '../components/ErrorMessage';
import Thumbnail from '../components/Thumbnail';
import PlaylistGrid from '../components/PlaylistGrid';
@ -12,18 +11,17 @@ import Parallax from '../components/Parallax';
import NiceNumber from '../components/NiceNumber';
import Loader from '../components/Loader';
import Icon from '../components/Icon';
import * as helpers from '../helpers';
import * as coreActions from '../services/core/actions';
import * as uiActions from '../services/ui/actions';
import * as mopidyActions from '../services/mopidy/actions';
import * as spotifyActions from '../services/spotify/actions';
import {
isLoading,
getFromUri,
sourceIcon,
} from '../util/helpers';
import { collate } from '../util/format';
class User extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.setWindowTitle();
this.props.coreActions.loadUser(this.props.uri);
@ -61,15 +59,15 @@ class User extends React.Component {
}
isMe() {
const userid = helpers.getFromUri('userid', this.props.uri);
const userid = getFromUri('userid', this.props.uri);
return (this.props.me && this.props.me.id && this.props.me.id == userid);
}
render() {
const user_id = helpers.getFromUri('userid', this.props.uri);
const user_id = getFromUri('userid', this.props.uri);
if (!this.props.user) {
if (helpers.isLoading(this.props.load_queue, [`spotify_users/${user_id}`, `spotify_users/${user_id}/playlists/?`])) {
if (isLoading(this.props.load_queue, [`spotify_users/${user_id}`, `spotify_users/${user_id}/playlists/?`])) {
return <Loader body loading />
}
return (
@ -83,7 +81,7 @@ Could not find user with URI "
);
}
const user = helpers.collate(this.props.user, { playlists: this.props.playlists });
const user = collate(this.props.user, { playlists: this.props.playlists });
if (user && user.images) {
var image = user.images.huge;
@ -112,7 +110,7 @@ Could not find user with URI "
</div>
<h2>
<ul className="details">
{!this.props.slim_mode ? <li className="source"><Icon type="fontawesome" name={helpers.sourceIcon(user.uri)} /></li> : null}
{!this.props.slim_mode ? <li className="source"><Icon type="fontawesome" name={sourceIcon(user.uri)} /></li> : null}
{user.playlists_total ? (
<li>
<NiceNumber value={user.playlists_total} />

View File

@ -2,21 +2,17 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Header from '../../components/Header';
import Icon from '../../components/Icon';
import CategoryGrid from '../../components/CategoryGrid';
import Loader from '../../components/Loader';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
import * as spotifyActions from '../../services/spotify/actions';
import {
isLoading,
} from '../../util/helpers';
class DiscoverCategories extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
// Check for an empty category index, or where we've only got one loaded
// This would be the case if you've refreshed from within a category and only loaded
@ -28,7 +24,7 @@ class DiscoverCategories extends React.Component {
}
render() {
if (helpers.isLoading(this.props.load_queue, ['spotify_browse/categories'])) {
if (isLoading(this.props.load_queue, ['spotify_browse/categories'])) {
return (
<div className="view discover-categories-view">
<Header icon="grid" title="Genre / Mood" />

View File

@ -2,22 +2,17 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Header from '../../components/Header';
import Icon from '../../components/Icon';
import PlaylistGrid from '../../components/PlaylistGrid';
import LazyLoadListener from '../../components/LazyLoadListener';
import Loader from '../../components/Loader';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
import * as spotifyActions from '../../services/spotify/actions';
import { isLoading } from '../../util/helpers';
import { collate } from '../../util/format';
class DiscoverCategory extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.loadCategory();
this.setWindowTitle();
@ -63,7 +58,7 @@ class DiscoverCategory extends React.Component {
}
render() {
if (helpers.isLoading(this.props.load_queue, ['spotify_browse/categories/'])) {
if (isLoading(this.props.load_queue, ['spotify_browse/categories/'])) {
return (
<div className="view discover-categories-view">
<Header>
@ -79,7 +74,7 @@ class DiscoverCategory extends React.Component {
return null;
}
const category = helpers.collate(this.props.category, { playlists: this.props.playlists });
const category = collate(this.props.category, { playlists: this.props.playlists });
return (
<div className="view discover-categories-view">

View File

@ -2,24 +2,17 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Link from '../../components/Link';
import PlaylistGrid from '../../components/PlaylistGrid';
import Header from '../../components/Header';
import Icon from '../../components/Icon';
import Parallax from '../../components/Parallax';
import Loader from '../../components/Loader';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions';
import { isLoading } from '../../util/helpers';
class DiscoverFeatured extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.props.uiActions.setWindowTitle('Featured playlists');
if (!this.props.featured_playlists) {
@ -58,7 +51,7 @@ class DiscoverFeatured extends React.Component {
}
render() {
if (helpers.isLoading(this.props.load_queue, ['spotify_browse/featured-playlists'])) {
if (isLoading(this.props.load_queue, ['spotify_browse/featured-playlists'])) {
return (
<div className="view discover-featured-view preserve-3d">
<Header className="overlay" uiActions={this.props.uiActions}>

View File

@ -2,25 +2,19 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Link from '../../components/Link';
import Header from '../../components/Header';
import Icon from '../../components/Icon';
import AlbumGrid from '../../components/AlbumGrid';
import Parallax from '../../components/Parallax';
import LazyLoadListener from '../../components/LazyLoadListener';
import Loader from '../../components/Loader';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions';
import { isLoading } from '../../util/helpers';
import { collate } from '../../util/format';
class DiscoverNewReleases extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.props.uiActions.setWindowTitle('New releases');
@ -70,7 +64,7 @@ class DiscoverNewReleases extends React.Component {
}
render() {
if (helpers.isLoading(this.props.load_queue, ['spotify_browse/new-releases'])) {
if (isLoading(this.props.load_queue, ['spotify_browse/new-releases'])) {
return (
<div className="view discover-new-releases-view">
<Header>
@ -94,7 +88,7 @@ class DiscoverNewReleases extends React.Component {
// Pull the first playlist out and we'll use this as a banner
let first_album = albums[0];
if (first_album) {
first_album = helpers.collate(first_album, { artists: this.props.artists });
first_album = collate(first_album, { artists: this.props.artists });
}
const options = (

View File

@ -3,10 +3,6 @@ import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import InputRange from 'react-input-range';
import Header from '../../components/Header';
import LinksSentence from '../../components/LinksSentence';
import ArtistGrid from '../../components/ArtistGrid';
import AlbumGrid from '../../components/AlbumGrid';
import TrackList from '../../components/TrackList';
import Thumbnail from '../../components/Thumbnail';
@ -17,11 +13,16 @@ import URILink from '../../components/URILink';
import ContextMenuTrigger from '../../components/ContextMenuTrigger';
import RelatedArtists from '../../components/RelatedArtists';
import Icon from '../../components/Icon';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions';
import {
isLoading,
getFromUri,
uriType,
titleCase,
} from '../../util/helpers';
import { arrayOf } from '../../util/arrays';
class Discover extends React.Component {
constructor(props) {
@ -190,7 +191,7 @@ class Discover extends React.Component {
e,
context: 'track',
items: tracks,
uris: helpers.arrayOf('uri', tracks),
uris: arrayOf('uri', tracks),
};
this.props.uiActions.showContextMenu(data);
}
@ -202,7 +203,7 @@ class Discover extends React.Component {
const seeds = seeds_string.split('_').join(':').split(',');
for (let i = 0; i < seeds.length; i++) {
switch (helpers.uriType(seeds[i])) {
switch (uriType(seeds[i])) {
case 'artist':
this.props.spotifyActions.getArtist(seeds[i]);
break;
@ -263,7 +264,7 @@ class Discover extends React.Component {
for (let i = 0; i < this.state.seeds.length; i++) {
const uri = this.state.seeds[i];
switch (helpers.uriType(uri)) {
switch (uriType(uri)) {
case 'track':
if (typeof (this.props.tracks[uri]) !== 'undefined') {
seeds_objects.push(this.props.tracks[uri]);
@ -287,7 +288,7 @@ class Discover extends React.Component {
break;
case 'genre':
var name = helpers.getFromUri('genreid', uri);
var name = getFromUri('genreid', uri);
seeds_objects.push({
name: (name.charAt(0).toUpperCase() + name.slice(1)).replace('-', ' '),
uri,
@ -301,7 +302,7 @@ class Discover extends React.Component {
<div className="seeds">
{
seeds_objects.map((seed, index) => {
const type = helpers.uriType(seed.uri);
const type = uriType(seed.uri);
let images = null;
if (seed.images) {
if (type == 'artist') {
@ -318,7 +319,7 @@ class Discover extends React.Component {
{images ? <URILink className="thumbnail-wrapper" type={type} uri={seed.uri}><Thumbnail images={images} circle={seed.type == 'artist'} size="small" /></URILink> : null}
<div className="seed__details">
<div className="seed__label">
<span className="seed__label__text">{helpers.titleCase(type)}</span>
<span className="seed__label__text">{titleCase(type)}</span>
<Icon name="close" className="seed__label__remove" onClick={() => this.removeSeed(index)} />
</div>
<div className="seed__label__name">{seed.name}</div>
@ -358,7 +359,7 @@ class Discover extends React.Component {
enabled_tunabilities.push(tunability);
} else {
addable_tunabilities.push({
label: helpers.titleCase(tunability.name),
label: titleCase(tunability.name),
value: tunability.name,
});
}
@ -370,7 +371,7 @@ class Discover extends React.Component {
{enabled_tunabilities.map((tunability) => (
<div className="field tunability range" key={tunability.name}>
<div className="tunability__label">
{helpers.titleCase(tunability.name)}
{titleCase(tunability.name)}
<span className="remove" onClick={(e) => this.toggleTunability(tunability.name)}>
<Icon name="close" />
</span>
@ -476,7 +477,7 @@ class Discover extends React.Component {
}
render() {
const is_loading = helpers.isLoading(this.props.load_queue, ['spotify_recommendations']);
const is_loading = isLoading(this.props.load_queue, ['spotify_recommendations']);
const addable_tunabilities = [];
for (const key in this.state.tunabilities) {
if (this.state.tunabilities.hasOwnProperty(key)) {
@ -488,7 +489,7 @@ class Discover extends React.Component {
if (!tunability.enabled) {
addable_tunabilities.push({
label: helpers.titleCase(tunability.name),
label: titleCase(tunability.name),
value: tunability.name,
});
}

View File

@ -2,7 +2,6 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import AlbumGrid from '../../components/AlbumGrid';
import List from '../../components/List';
import Header from '../../components/Header';
@ -10,13 +9,16 @@ import DropdownField from '../../components/Fields/DropdownField';
import FilterField from '../../components/Fields/FilterField';
import LazyLoadListener from '../../components/LazyLoadListener';
import Icon from '../../components/Icon';
import * as helpers from '../../helpers';
import * as coreActions from '../../services/core/actions';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as googleActions from '../../services/google/actions';
import * as spotifyActions from '../../services/spotify/actions';
import {
uriSource,
} from '../../util/helpers';
import { sortItems, applyFilter } from '../../util/arrays';
import { collate } from '../../util/format';
class LibraryAlbums extends React.Component {
constructor(props) {
@ -101,7 +103,7 @@ class LibraryAlbums extends React.Component {
if (this.props.albums && this.props.library_albums) {
for (let i = 0; i < this.props.library_albums.length; i++) {
const uri = this.props.library_albums[i];
if (!this.props.albums.hasOwnProperty(uri) && helpers.uriSource(uri) == 'local') {
if (!this.props.albums.hasOwnProperty(uri) && uriSource(uri) == 'local') {
uris.push(uri);
}
@ -152,7 +154,7 @@ class LibraryAlbums extends React.Component {
for (var uri of this.props.mopidy_library_albums) {
// Construct item placeholder. This is used as Mopidy needs to
// lookup ref objects to get the full object which can take some time
var source = helpers.uriSource(uri);
var source = uriSource(uri);
var album = {
uri,
source,
@ -169,7 +171,7 @@ class LibraryAlbums extends React.Component {
for (var uri of this.props.google_library_albums) {
// Construct item placeholder. This is used as Mopidy needs to
// lookup ref objects to get the full object which can take some time
var source = helpers.uriSource(uri);
var source = uriSource(uri);
var album = {
uri,
source,
@ -185,15 +187,15 @@ class LibraryAlbums extends React.Component {
// Collate each album into it's full object (including nested artists)
for (let i = 0; i < albums.length; i++) {
albums[i] = helpers.collate(albums[i], { artists: this.props.artists });
albums[i] = collate(albums[i], { artists: this.props.artists });
}
if (this.props.sort) {
albums = helpers.sortItems(albums, this.props.sort, this.props.sort_reverse);
albums = sortItems(albums, this.props.sort, this.props.sort_reverse);
}
if (this.state.filter && this.state.filter !== '') {
albums = helpers.applyFilter('name', this.state.filter, albums);
albums = applyFilter('name', this.state.filter, albums);
}
// Apply our lazy-load-rendering

View File

@ -2,8 +2,6 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Link from '../../components/Link';
import Header from '../../components/Header';
import ArtistGrid from '../../components/ArtistGrid';
import List from '../../components/List';
@ -11,12 +9,14 @@ import DropdownField from '../../components/Fields/DropdownField';
import FilterField from '../../components/Fields/FilterField';
import LazyLoadListener from '../../components/LazyLoadListener';
import Icon from '../../components/Icon';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions';
import * as googleActions from '../../services/google/actions';
import {
uriSource,
} from '../../util/helpers';
import { sortItems, applyFilter } from '../../util/arrays';
class LibraryArtists extends React.Component {
constructor(props) {
@ -126,7 +126,7 @@ class LibraryArtists extends React.Component {
for (uri of this.props.mopidy_library_artists) {
// Construct item placeholder. This is used as Mopidy needs to
// lookup ref objects to get the full object which can take some time
var source = helpers.uriSource(uri);
var source = uriSource(uri);
var artist = {
uri,
source,
@ -145,7 +145,7 @@ class LibraryArtists extends React.Component {
for (uri of this.props.google_library_artists) {
// Construct item placeholder. This is used as Mopidy needs to
// lookup ref objects to get the full object which can take some time
var source = helpers.uriSource(uri);
var source = uriSource(uri);
var artist = {
uri,
source,
@ -170,11 +170,11 @@ class LibraryArtists extends React.Component {
}
if (this.props.sort) {
artists = helpers.sortItems(artists, this.props.sort, this.props.sort_reverse);
artists = sortItems(artists, this.props.sort, this.props.sort_reverse);
}
if (this.state.filter !== '') {
artists = helpers.applyFilter('name', this.state.filter, artists);
artists = applyFilter('name', this.state.filter, artists);
}
// Apply our lazy-load-rendering

View File

@ -2,34 +2,23 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Route, Switch } from 'react-router-dom';
import Link from '../../components/Link';
import Header from '../../components/Header';
import List from '../../components/List';
import TrackList from '../../components/TrackList';
import GridItem from '../../components/GridItem';
import DropdownField from '../../components/Fields/DropdownField';
import Icon from '../../components/Icon';
import URILink from '../../components/URILink';
import ErrorBoundary from '../../components/ErrorBoundary';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import {
formatImages,
} from '../../util/helpers';
class LibraryBrowse extends React.Component {
constructor(props) {
super(props);
}
class LibraryBrowse extends React.Component {
componentDidMount() {
this.loadDirectory();
this.props.uiActions.setWindowTitle('Browse');
}
componentWillReceiveProps(nextProps) {
componentWillReceiveProps(nextProps) {
// mopidy goes online
if (!this.props.mopidy_connected && nextProps.mopidy_connected) {
this.loadDirectory(nextProps);
@ -45,7 +34,7 @@ class LibraryBrowse extends React.Component {
render() {
const grid_items = [];
if (this.props.directory) {
for (const subdirectory of this.props.directory.subdirectories) {
for (const subdirectory of this.props.directory.subdirectories) {
switch (subdirectory.name) {
case 'Dirble':
subdirectory.icons = ['/iris/assets/backgrounds/browse-dirble.jpg'];
@ -93,7 +82,7 @@ class LibraryBrowse extends React.Component {
grid_items.push({
name: subdirectory.name,
link: `/library/browse/${encodeURIComponent(subdirectory.uri)}`,
icons: helpers.formatImages(subdirectory.icons),
icons: formatImages(subdirectory.icons),
});
}
}
@ -114,7 +103,7 @@ class LibraryBrowse extends React.Component {
item={item}
key={index}
link={item.link}
type="browse"
type="browse"
/>
),
)
@ -139,4 +128,4 @@ const mapDispatchToProps = (dispatch) => ({
mopidyActions: bindActionCreators(mopidyActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(LibraryBrowse);
export default connect(mapStateToProps, mapDispatchToProps)(LibraryBrowse);

View File

@ -2,7 +2,6 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Loader from '../../components/Loader';
import Header from '../../components/Header';
import List from '../../components/List';
@ -12,17 +11,15 @@ import DropdownField from '../../components/Fields/DropdownField';
import Icon from '../../components/Icon';
import URILink from '../../components/URILink';
import ErrorBoundary from '../../components/ErrorBoundary';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions';
import {
isLoading,
} from '../../util/helpers';
import { arrayOf, sortItems } from '../../util/arrays';
class LibraryBrowseDirectory extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.props.uiActions.setWindowTitle('Browse');
this.loadDirectory();
@ -51,7 +48,7 @@ class LibraryBrowseDirectory extends React.Component {
}
playAll(e, tracks) {
const tracks_uris = helpers.arrayOf('uri', tracks);
const tracks_uris = arrayOf('uri', tracks);
this.props.mopidyActions.playURIs(tracks_uris, `iris:browse:${this.props.uri}`);
this.props.uiActions.hideContextMenu();
}
@ -136,7 +133,7 @@ class LibraryBrowseDirectory extends React.Component {
title = title.charAt(0).toUpperCase() + title.slice(1);
}
if (!this.props.directory || helpers.isLoading(this.props.load_queue, ['mopidy_browse'])) {
if (!this.props.directory || isLoading(this.props.load_queue, ['mopidy_browse'])) {
return (
<div className="view library-local-view">
<Header icon="music" title={title} uiActions={this.props.uiActions} />
@ -146,10 +143,10 @@ class LibraryBrowseDirectory extends React.Component {
}
let tracks = (this.props.directory.tracks && this.props.directory.tracks.length > 0 ? this.props.directory.tracks : null);
tracks = helpers.sortItems(tracks, 'name');
tracks = sortItems(tracks, 'name');
let subdirectories = (this.props.directory.subdirectories && this.props.directory.subdirectories.length > 0 ? this.props.directory.subdirectories : null);
subdirectories = helpers.sortItems(subdirectories, 'name');
subdirectories = sortItems(subdirectories, 'name');
const view_options = [
{

View File

@ -3,7 +3,6 @@ import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Link from '../../components/Link';
import PlaylistGrid from '../../components/PlaylistGrid';
import List from '../../components/List';
import DropdownField from '../../components/Fields/DropdownField';
@ -11,12 +10,11 @@ import Header from '../../components/Header';
import FilterField from '../../components/Fields/FilterField';
import LazyLoadListener from '../../components/LazyLoadListener';
import Icon from '../../components/Icon';
import * as helpers from '../../helpers';
import * as coreActions from '../../services/core/actions';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions';
import { applyFilter, removeDuplicates, sortItems } from '../../util/arrays';
class LibraryPlaylists extends React.Component {
constructor(props) {
@ -126,12 +124,12 @@ class LibraryPlaylists extends React.Component {
}
if (this.props.sort) {
playlists = helpers.sortItems(playlists, this.props.sort, this.props.sort_reverse);
playlists = sortItems(playlists, this.props.sort, this.props.sort_reverse);
}
playlists = helpers.removeDuplicates(playlists);
playlists = removeDuplicates(playlists);
if (this.state.filter !== '') {
playlists = helpers.applyFilter('name', this.state.filter, playlists);
playlists = applyFilter('name', this.state.filter, playlists);
}
// Apply our lazy-load-rendering

View File

@ -2,24 +2,17 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Loader from '../../components/Loader';
import TrackList from '../../components/TrackList';
import Header from '../../components/Header';
import LazyLoadListener from '../../components/LazyLoadListener';
import Icon from '../../components/Icon';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions';
import { isLoading } from '../../util/helpers';
class LibraryTracks extends React.Component {
constructor(props) {
super(props);
}
// on render
componentDidMount() {
this.props.uiActions.setWindowTitle('Tracks');
@ -46,7 +39,7 @@ class LibraryTracks extends React.Component {
render() {
// Note trailing "?" makes sure our context menu in_library checks doesn't interfere
if (helpers.isLoading(this.props.load_queue, ['spotify_me/tracks?'])) {
if (isLoading(this.props.load_queue, ['spotify_me/tracks?'])) {
return (
<div className="view library-tracks-view">
<Header icon="music" title="My tracks" />

View File

@ -2,8 +2,6 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import Loader from '../../components/Loader';
import Modal from './Modal';
import Icon from '../../components/Icon';
@ -12,7 +10,8 @@ import * as coreActions from '../../services/core/actions';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions';
import * as helpers from '../../helpers';
import { sourceIcon } from '../../util/helpers';
import { sortItems } from '../../util/arrays';
class AddToPlaylist extends React.Component {
constructor(props) {
@ -50,7 +49,7 @@ class AddToPlaylist extends React.Component {
if (playlists[uri].can_edit) editablePlaylists.push(playlists[uri]);
}
editablePlaylists = helpers.sortItems(editablePlaylists, 'name');
editablePlaylists = sortItems(editablePlaylists, 'name');
const isLoading = spotify_library_playlists_status === 'running';
@ -71,7 +70,7 @@ class AddToPlaylist extends React.Component {
<Thumbnail images={playlist.images} size="small" />
<h4 className="list__item__name">{ playlist.name }</h4>
<ul className="list__item__details details">
<li><Icon type="fontawesome" className="source" name={helpers.sourceIcon(playlist.uri)} /></li>
<li><Icon type="fontawesome" className="source" name={sourceIcon(playlist.uri)} /></li>
<li>
{ playlist.tracks_total ? (
<span className="mid_grey-text">

View File

@ -2,18 +2,13 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import Link from '../../components/Link';
import Modal from './Modal';
import Icon from '../../components/Icon';
import * as coreActions from '../../services/core/actions';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions';
import * as helpers from '../../helpers';
class AddToQueue extends React.Component {
class AddToQueue extends React.Component {
constructor(props) {
super(props);
this.state = {
@ -46,7 +41,7 @@ class AddToQueue extends React.Component {
<input
type="text"
onChange={(e) => this.setState({ uris: e.target.value })}
value={this.state.uris}
value={this.state.uris}
/>
</div>
</div>
@ -61,7 +56,7 @@ class AddToQueue extends React.Component {
type="radio"
name="next"
checked={!this.state.next}
onChange={(e) => this.setState({ next: false })}
onChange={(e) => this.setState({ next: false })}
/>
<span className="label">End</span>
</label>
@ -70,7 +65,7 @@ class AddToQueue extends React.Component {
type="radio"
name="next"
checked={this.state.next}
onChange={(e) => this.setState({ next: true })}
onChange={(e) => this.setState({ next: true })}
/>
<span className="label">After current track</span>
</label>
@ -99,4 +94,4 @@ const mapDispatchToProps = (dispatch) => ({
spotifyActions: bindActionCreators(spotifyActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(AddToQueue);
export default connect(mapStateToProps, mapDispatchToProps)(AddToQueue);

View File

@ -2,16 +2,11 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import Link from '../../components/Link';
import Modal from './Modal';
import Icon from '../../components/Icon';
import * as coreActions from '../../services/core/actions';
import * as uiActions from '../../services/ui/actions';
import * as helpers from '../../helpers';
class CreatePlaylist extends React.Component {
class CreatePlaylist extends React.Component {
constructor(props) {
super(props);
this.state = {
@ -48,7 +43,7 @@ class CreatePlaylist extends React.Component {
}
renderFields() {
switch (this.state.scheme) {
switch (this.state.scheme) {
case 'spotify':
return (
<div>
@ -58,7 +53,7 @@ class CreatePlaylist extends React.Component {
<input
type="text"
onChange={(e) => this.setState({ name: e.target.value })}
value={this.state.name}
value={this.state.name}
/>
</div>
</div>
@ -70,7 +65,7 @@ class CreatePlaylist extends React.Component {
type="text"
onChange={(e) => this.setState({ description: e.target.value })}
value={this.state.description}
value={this.state.description}
/>
</div>
</div>
@ -85,7 +80,7 @@ class CreatePlaylist extends React.Component {
type="checkbox"
name="is_public"
checked={this.state.is_public}
onChange={(e) => this.setState({ is_public: !this.state.is_public })}
onChange={(e) => this.setState({ is_public: !this.state.is_public })}
/>
<span className="label">Public</span>
</label>
@ -94,7 +89,7 @@ class CreatePlaylist extends React.Component {
type="checkbox"
name="is_collaborative"
checked={this.state.is_collaborative}
onChange={(e) => this.setState({ is_collaborative: !this.state.is_collaborative })}
onChange={(e) => this.setState({ is_collaborative: !this.state.is_collaborative })}
/>
<span className="label">Collaborative</span>
</label>
@ -112,7 +107,7 @@ class CreatePlaylist extends React.Component {
<input
type="text"
onChange={(e) => this.setState({ name: e.target.value })}
value={this.state.name}
value={this.state.name}
/>
</div>
</div>
@ -138,7 +133,7 @@ class CreatePlaylist extends React.Component {
name="scheme"
value="spotify"
checked={this.state.scheme == 'spotify'}
onChange={(e) => this.setState({ scheme: e.target.value })}
onChange={(e) => this.setState({ scheme: e.target.value })}
/>
<span className="label">Spotify</span>
</label>
@ -148,7 +143,7 @@ class CreatePlaylist extends React.Component {
name="scheme"
value="m3u"
checked={this.state.scheme == 'm3u'}
onChange={(e) => this.setState({ scheme: e.target.value })}
onChange={(e) => this.setState({ scheme: e.target.value })}
/>
<span className="label">Mopidy</span>
</label>
@ -174,4 +169,4 @@ const mapDispatchToProps = (dispatch) => ({
uiActions: bindActionCreators(uiActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(CreatePlaylist);
export default connect(mapStateToProps, mapDispatchToProps)(CreatePlaylist);

View File

@ -2,24 +2,19 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import Modal from './Modal';
import Link from '../../components/Link';
import Icon from '../../components/Icon';
import ColourField from '../../components/Fields/ColourField';
import IconField from '../../components/Fields/IconField';
import TextField from '../../components/Fields/TextField';
import * as pusherActions from '../../services/pusher/actions';
import * as uiActions from '../../services/ui/actions';
import * as helpers from '../../helpers';
import { scrollTo, generateGuid } from '../../util/helpers';
class EditCommand extends React.Component {
class EditCommand extends React.Component {
constructor(props) {
super(props);
this.state = {
id: helpers.generateGuid(),
id: generateGuid(),
icon: 'power_settings_new',
name: '',
colour: '',
@ -49,7 +44,7 @@ class EditCommand extends React.Component {
// A bit hacky, but wait for a moment to allow the back navigation
// and then scroll down to our commands list
setTimeout(() => {
helpers.scrollTo('#commands-setup');
scrollTo('#commands-setup');
},
10);
@ -63,12 +58,12 @@ class EditCommand extends React.Component {
// A bit hacky, but wait for a moment to allow the back navigation
// and then scroll down to our commands list
setTimeout(() => {
helpers.scrollTo('#commands-setup');
scrollTo('#commands-setup');
},
10);
}
render() {
render() {
const icons = [
'power_settings_new',
'eject',
@ -114,10 +109,10 @@ class EditCommand extends React.Component {
return (
<Modal className="modal--create-command">
<h1>
{this.props.command ? 'Edit' : 'Create'}
{' '}
command
<h1>
{this.props.command ? 'Edit' : 'Create'}
{' '}
command
</h1>
<form onSubmit={(e) => this.handleSubmit(e)}>
@ -129,7 +124,7 @@ command
<TextField
name="name"
value={this.state.name}
onChange={(value) => this.setState({ name: value })}
onChange={(value) => this.setState({ name: value })}
/>
</div>
</div>
@ -141,7 +136,7 @@ command
<div className="input">
<ColourField
colour={this.state.colour}
onChange={(colour) => this.setState({ colour })}
onChange={(colour) => this.setState({ colour })}
/>
</div>
</div>
@ -154,7 +149,7 @@ command
<IconField
icon={this.state.icon}
icons={icons}
onChange={(icon) => this.setState({ icon })}
onChange={(icon) => this.setState({ icon })}
/>
</div>
</div>
@ -167,7 +162,7 @@ command
<TextField
name="url"
value={this.state.url}
onChange={(value) => this.setState({ url: value })}
onChange={(value) => this.setState({ url: value })}
/>
</div>
</div>
@ -183,7 +178,7 @@ command
name="method"
value="GET"
checked={this.state.method == 'GET'}
onChange={(e) => this.setState({ method: e.target.value })}
onChange={(e) => this.setState({ method: e.target.value })}
/>
<span className="label">GET</span>
</label>
@ -193,14 +188,14 @@ command
name="method"
value="POST"
checked={this.state.method == 'POST'}
onChange={(e) => this.setState({ method: e.target.value })}
onChange={(e) => this.setState({ method: e.target.value })}
/>
<span className="label">POST</span>
</label>
</div>
</div>
{this.state.method == 'POST' && (
{this.state.method == 'POST' && (
<div className="field textarea white">
<div className="name">
Data
@ -209,10 +204,10 @@ command
<textarea
name="command"
value={this.state.post_data}
onChange={(e) => this.setState({ post_data: e.target.value })}
onChange={(e) => this.setState({ post_data: e.target.value })}
/>
</div>
</div>
</div>
)}
<div className="field textarea white">
@ -223,7 +218,7 @@ command
<textarea
name="headers"
value={this.state.additional_headers}
onChange={(e) => this.setState({ additional_headers: e.target.value })}
onChange={(e) => this.setState({ additional_headers: e.target.value })}
/>
</div>
</div>
@ -253,4 +248,4 @@ const mapDispatchToProps = (dispatch) => ({
uiActions: bindActionCreators(uiActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(EditCommand);
export default connect(mapStateToProps, mapDispatchToProps)(EditCommand);

View File

@ -2,18 +2,14 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import Link from '../../components/Link';
import Modal from './Modal';
import Icon from '../../components/Icon';
import * as coreActions from '../../services/core/actions';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions';
import * as helpers from '../../helpers';
import { uriSource } from '../../util/helpers';
class EditPlaylist extends React.Component {
class EditPlaylist extends React.Component {
constructor(props) {
super(props);
this.state = {
@ -26,7 +22,7 @@ class EditPlaylist extends React.Component {
};
}
componentDidMount() {
componentDidMount() {
this.props.uiActions.setWindowTitle('Edit playlist');
if (this.props.playlist) {
@ -37,7 +33,7 @@ class EditPlaylist extends React.Component {
collaborative: (this.props.playlist.collaborative == true),
});
} else {
switch (helpers.uriSource(this.props.uri)) {
switch (helpers.uriSource(this.props.uri)) {
case 'spotify':
this.props.spotifyActions.getPlaylist(this.props.uri);
this.props.spotifyActions.following(this.props.uri);
@ -52,7 +48,7 @@ class EditPlaylist extends React.Component {
}
}
componentWillReceiveProps(nextProps) {
componentWillReceiveProps(nextProps) {
// Playlist just loaded
if (!this.props.playlist && nextProps.playlist) {
this.setState({
@ -84,7 +80,7 @@ class EditPlaylist extends React.Component {
this.state.image,
);
window.history.back();
return false;
return false;
}
setImage(e) {
@ -104,7 +100,7 @@ class EditPlaylist extends React.Component {
}
renderFields() {
switch (helpers.uriSource(this.props.uri)) {
switch (uriSource(this.props.uri)) {
case 'spotify':
return (
<div>
@ -114,7 +110,7 @@ class EditPlaylist extends React.Component {
<input
type="text"
onChange={(e) => this.setState({ name: e.target.value })}
value={this.state.name}
value={this.state.name}
/>
</div>
</div>
@ -124,7 +120,7 @@ class EditPlaylist extends React.Component {
<input
type="text"
onChange={(e) => this.setState({ description: e.target.value })}
value={this.state.description}
value={this.state.description}
/>
</div>
</div>
@ -134,7 +130,7 @@ class EditPlaylist extends React.Component {
<input
type="file"
placeholder="Leave empty to keep existing image"
onChange={(e) => this.setImage(e)}
onChange={(e) => this.setImage(e)}
/>
<div className="description">
JPEG only, 256kB max. Leave empty to keep cover image unchanged.
@ -151,7 +147,7 @@ class EditPlaylist extends React.Component {
type="checkbox"
name="playlist_private"
checked={this.state.public}
onChange={(e) => this.setState({ public: !this.state.public })}
onChange={(e) => this.setState({ public: !this.state.public })}
/>
<span className="label">Public</span>
</label>
@ -160,7 +156,7 @@ class EditPlaylist extends React.Component {
type="checkbox"
name="collaborative"
checked={this.state.collaborative}
onChange={(e) => this.setState({ collaborative: !this.state.collaborative })}
onChange={(e) => this.setState({ collaborative: !this.state.collaborative })}
/>
<span className="label">Collaborative</span>
</label>
@ -179,7 +175,7 @@ class EditPlaylist extends React.Component {
<input
type="text"
onChange={(e) => this.setState({ name: e.target.value })}
value={this.state.name}
value={this.state.name}
/>
</div>
</div>
@ -206,7 +202,7 @@ class EditPlaylist extends React.Component {
}
}
const mapStateToProps = (state, ownProps) => {
const mapStateToProps = (state, ownProps) => {
// Decode the URI, and then re-encode selected characters
// This is needed as Mopidy encodes *some* characters in playlist URIs (but not other characters)
// We need to retain ":" because this a reserved URI separator

View File

@ -2,18 +2,17 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ReactGA from 'react-ga';
import Link from '../../components/Link';
import Modal from './Modal';
import Icon from '../../components/Icon';
import * as coreActions from '../../services/core/actions';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as spotifyActions from '../../services/spotify/actions';
import * as pusherActions from '../../services/pusher/actions';
import * as helpers from '../../helpers';
import {
uriSource,
uriType,
} from '../../util/helpers';
class EditRadio extends React.Component {
constructor(props) {
@ -110,7 +109,7 @@ class EditRadio extends React.Component {
}
for (let i = 0; i < uris.length; i++) {
if (helpers.uriSource(uris[i]) !== 'spotify') {
if (uriSource(uris[i]) !== 'spotify') {
this.setState({ error_message: 'Non-Spotify URIs not supported' });
return;
} if (seeds.indexOf(uris[i]) > -1) {
@ -120,7 +119,7 @@ class EditRadio extends React.Component {
}
// Resolve
switch (helpers.uriType(uris[i])) {
switch (uriType(uris[i])) {
case 'track':
this.props.spotifyActions.getTrack(uris[i]);
break;
@ -155,7 +154,7 @@ class EditRadio extends React.Component {
for (let i = 0; i < this.state.seeds.length && i < 5; i++) {
const uri = this.state.seeds[i];
if (uri) {
if (helpers.uriType(uri) == 'artist') {
if (uriType(uri) == 'artist') {
if (this.props.artists && this.props.artists.hasOwnProperty(uri)) {
seeds.push(this.props.artists[uri]);
} else {
@ -164,7 +163,7 @@ class EditRadio extends React.Component {
uri,
});
}
} else if (helpers.uriType(uri) == 'track') {
} else if (uriType(uri) == 'track') {
if (this.props.tracks && this.props.tracks.hasOwnProperty(uri)) {
seeds.push(this.props.tracks[uri]);
} else {
@ -195,7 +194,7 @@ class EditRadio extends React.Component {
{!seed.unresolved ? (
<span className="mid_grey-text">
&nbsp;(
{helpers.uriType(seed.uri)}
{uriType(seed.uri)}
)
</span>
) : null}

View File

@ -1,19 +1,11 @@
import React from 'react';
import { connect } from 'react-redux';
import { createStore, bindActionCreators } from 'redux';
import { bindActionCreators } from 'redux';
import Modal from './Modal';
import Thumbnail from '../../components/Thumbnail';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
class ImageZoom extends React.Component {
constructor(props) {
super(props);
}
class ImageZoom extends React.Component {
componentDidMount() {
this.props.uiActions.setWindowTitle('Zoomed image');
}
@ -33,4 +25,4 @@ const mapDispatchToProps = (dispatch) => ({
uiActions: bindActionCreators(uiActions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(ImageZoom);
export default connect(mapStateToProps, mapDispatchToProps)(ImageZoom);

View File

@ -2,14 +2,12 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Modal from './Modal';
import * as coreActions from '../../services/core/actions';
import * as uiActions from '../../services/ui/actions';
import * as pusherActions from '../../services/pusher/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as helpers from '../../helpers';
import { queryString, isHosted } from '../../util/helpers';
class InitialSetup extends React.Component {
constructor(props) {
@ -39,8 +37,8 @@ class InitialSetup extends React.Component {
} = this.props;
// Check for url-parsed configuration values
const customHost = helpers.queryString('host', search);
const customPort = helpers.queryString('port', search);
const customHost = queryString('host', search);
const customPort = queryString('port', search);
if (customHost) this.setState({ host: customHost });
if (customPort) this.setState({ port: customPort });
@ -127,7 +125,7 @@ class InitialSetup extends React.Component {
</div>
</div>
{helpers.isHosted() ? null : (
{isHosted() ? null : (
<div className="field checkbox">
<div className="input">
<label>

View File

@ -1,20 +1,18 @@
import React from 'react';
import { connect } from 'react-redux';
import { createStore, bindActionCreators } from 'redux';
import { bindActionCreators } from 'redux';
import Link from '../../components/Link';
import Modal from './Modal';
import Thumbnail from '../../components/Thumbnail';
import LinksSentence from '../../components/LinksSentence';
import Loader from '../../components/Loader';
import Icon from '../../components/Icon';
import ProgressSlider from '../../components/Fields/ProgressSlider';
import * as helpers from '../../helpers';
import * as uiActions from '../../services/ui/actions';
import * as mopidyActions from '../../services/mopidy/actions';
import * as geniusActions from '../../services/genius/actions';
import { isLoading } from '../../util/helpers';
const LyricsScroller = ({ content = '', time_position = 1, duration = 100 }) => {
const percent = ((time_position / duration) * 110).toFixed(4);
@ -123,7 +121,7 @@ class KioskMode extends React.Component {
const { lyrics, duration } = current_track || {};
if (helpers.isLoading(load_queue, ['genius_'])) {
if (isLoading(load_queue, ['genius_'])) {
return (
<div className="lyrics">
<Loader body loading />

View File

@ -1,16 +1,9 @@
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as helpers from '../../helpers';
import Icon from '../../components/Icon';
class Modal extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
$('body').addClass('modal-open');
}

View File

@ -1,15 +1,10 @@
import React from 'react';
import { connect } from 'react-redux';
import { createStore, bindActionCreators } from 'redux';
import Link from '../../components/Link';
import { bindActionCreators } from 'redux';
import Modal from './Modal';
import Icon from '../../components/Icon';
import * as uiActions from '../../services/ui/actions';
import * as pusherActions from '../../services/pusher/actions';
import * as helpers from '../../helpers';
class ShareConfiguration extends React.Component {
constructor(props) {
@ -223,7 +218,7 @@ class ShareConfiguration extends React.Component {
</div>
</label>
</div>
<div className="checkbox-group__item">
<label>
<input