Adding feedback to LastFm love/unlove; Using selectors for love/follow buttons
This commit is contained in:
@ -6,6 +6,7 @@ import * as spotifyActions from '../../services/spotify/actions';
|
||||
import { isLoading, getFromUri } from '../../util/helpers';
|
||||
import { i18n } from '../../locale';
|
||||
import { Button } from '../Button';
|
||||
import { makeLoadingSelector } from '../../util/selectors';
|
||||
|
||||
class FollowButton extends React.Component {
|
||||
remove = () => {
|
||||
@ -34,23 +35,16 @@ class FollowButton extends React.Component {
|
||||
removeText,
|
||||
spotify_authorized,
|
||||
is_following,
|
||||
load_queue,
|
||||
loading,
|
||||
} = this.props;
|
||||
|
||||
if (!uri) return null;
|
||||
|
||||
const working = isLoading(load_queue, [
|
||||
'spotify_me/tracks?',
|
||||
'spotify_me/albums?',
|
||||
'spotify_me/following?',
|
||||
`spotify_playlists/${getFromUri('playlistid', uri)}/followers?`,
|
||||
]);
|
||||
|
||||
if (!spotify_authorized) {
|
||||
return (
|
||||
<Button
|
||||
disabled
|
||||
working={working}
|
||||
working={loading}
|
||||
onClick={this.unauthorized}
|
||||
tracking={{ category: 'FollowButton', action: 'Add (disabled)' }}
|
||||
>
|
||||
@ -61,7 +55,7 @@ class FollowButton extends React.Component {
|
||||
return (
|
||||
<Button
|
||||
type="destructive"
|
||||
working={working}
|
||||
working={loading}
|
||||
onClick={this.remove}
|
||||
tracking={{ category: 'FollowButton', action: 'Remove' }}
|
||||
>
|
||||
@ -72,7 +66,7 @@ class FollowButton extends React.Component {
|
||||
return (
|
||||
<Button
|
||||
onClick={this.add}
|
||||
working={working}
|
||||
working={loading}
|
||||
tracking={{ category: 'FollowButton', action: 'Add' }}
|
||||
>
|
||||
{addText || i18n('actions.add_to_library')}
|
||||
@ -81,10 +75,23 @@ class FollowButton extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
load_queue: state.ui.load_queue,
|
||||
spotify_authorized: state.spotify.authorization,
|
||||
});
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const {
|
||||
uri,
|
||||
} = ownProps;
|
||||
|
||||
const loadingSelector = makeLoadingSelector([
|
||||
'spotify_me/tracks?',
|
||||
'spotify_me/albums?',
|
||||
'spotify_me/following?',
|
||||
`spotify_playlists/${getFromUri('playlistid', uri)}/followers?`,
|
||||
]);
|
||||
|
||||
return {
|
||||
loading: loadingSelector(state),
|
||||
spotify_authorized: state.spotify.authorization,
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
uiActions: bindActionCreators(uiActions, dispatch),
|
||||
|
||||
@ -6,6 +6,7 @@ import * as uiActions from '../../services/ui/actions';
|
||||
import * as lastfmActions from '../../services/lastfm/actions';
|
||||
import { i18n } from '../../locale';
|
||||
import Button from '../Button';
|
||||
import { makeLoadingSelector } from '../../util/selectors';
|
||||
|
||||
const FollowButton = ({
|
||||
uri,
|
||||
@ -14,7 +15,6 @@ const FollowButton = ({
|
||||
addText,
|
||||
removeText,
|
||||
is_loved,
|
||||
className: classNameProp = '',
|
||||
lastfm_authorized,
|
||||
uiActions: {
|
||||
createNotification,
|
||||
@ -23,6 +23,7 @@ const FollowButton = ({
|
||||
unloveTrack,
|
||||
loveTrack,
|
||||
},
|
||||
loading,
|
||||
}) => {
|
||||
const onRemove = () => unloveTrack(uri, artist, track);
|
||||
const onAdd = () => loveTrack(uri, artist, track);
|
||||
@ -33,17 +34,14 @@ const FollowButton = ({
|
||||
});
|
||||
};
|
||||
|
||||
if (!uri) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const className = `button ${classNameProp}`;
|
||||
if (!uri) return false;
|
||||
|
||||
if (!lastfm_authorized) {
|
||||
return (
|
||||
<Button
|
||||
disabled
|
||||
onClick={onDisabledClick}
|
||||
working={loading}
|
||||
tracking={{ category: 'Lastfm', action: 'Love', label: 'Disabled' }}
|
||||
>
|
||||
{addText || i18n('services.lastfm.love')}
|
||||
@ -54,6 +52,7 @@ const FollowButton = ({
|
||||
<Button
|
||||
type="destructive"
|
||||
onClick={onRemove}
|
||||
working={loading}
|
||||
tracking={{ category: 'Lastfm', action: 'Unlove' }}
|
||||
>
|
||||
{removeText || i18n('services.lastfm.unlove')}
|
||||
@ -63,6 +62,7 @@ const FollowButton = ({
|
||||
return (
|
||||
<Button
|
||||
onClick={onAdd}
|
||||
working={loading}
|
||||
tracking={{ category: 'Lastfm', action: 'Love' }}
|
||||
>
|
||||
{addText || i18n('services.lastfm.love')}
|
||||
@ -70,10 +70,13 @@ const FollowButton = ({
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
load_queue: state.ui.load_queue,
|
||||
lastfm_authorized: state.lastfm.authorization,
|
||||
});
|
||||
const mapStateToProps = (state) => {
|
||||
const loadingSelector = makeLoadingSelector(['love', 'unlove']);
|
||||
return {
|
||||
loading: loadingSelector(state),
|
||||
lastfm_authorized: state.lastfm.authorization,
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
uiActions: bindActionCreators(uiActions, dispatch),
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
collate,
|
||||
formatImages,
|
||||
@ -6,7 +7,8 @@ import {
|
||||
formatAlbum,
|
||||
} from '../../util/format';
|
||||
import { generateGuid } from '../../util/helpers';
|
||||
import { makeItemSelector } from '../../util/selectors';
|
||||
import { makeItemSelector, getItem } from '../../util/selectors';
|
||||
import URILink from '../../components/URILink';
|
||||
|
||||
const coreActions = require('../core/actions');
|
||||
const uiActions = require('../ui/actions');
|
||||
@ -357,34 +359,36 @@ export function getImages(context, uri) {
|
||||
|
||||
export function loveTrack(uri) {
|
||||
return (dispatch, getState) => {
|
||||
const track = getState().core.items[uri];
|
||||
if (getState().core.items[uri] !== undefined) {
|
||||
if (!track.artists) {
|
||||
dispatch(coreActions.handleException(
|
||||
'Could not love LastFM track',
|
||||
track,
|
||||
'Track has no artists',
|
||||
));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const asset = getItem(getState(), uri) || {};
|
||||
if (!asset) {
|
||||
dispatch(coreActions.handleException(
|
||||
'Could not love LastFM track',
|
||||
track,
|
||||
asset,
|
||||
'Could not find track in index',
|
||||
));
|
||||
return;
|
||||
}
|
||||
if (asset && !asset.artists) {
|
||||
dispatch(coreActions.handleException(
|
||||
'Could not love LastFM track',
|
||||
asset,
|
||||
'Track has no artists',
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
const artist = encodeURIComponent(track.artists[0].name);
|
||||
const params = `method=track.love&track=${track.name}&artist=${artist}`;
|
||||
const artist = encodeURIComponent(asset.artists[0].name);
|
||||
const params = `method=track.love&track=${asset.name}&artist=${artist}`;
|
||||
sendSignedRequest(dispatch, getState, params)
|
||||
.then(
|
||||
(response) => {
|
||||
() => {
|
||||
dispatch(coreActions.itemLoaded({
|
||||
uri,
|
||||
userloved: true,
|
||||
}));
|
||||
dispatch(uiActions.createNotification({
|
||||
content: <span>Loved <URILink uri={uri}>{asset ? asset.name : type}</URILink></span>,
|
||||
}));
|
||||
},
|
||||
);
|
||||
};
|
||||
@ -392,34 +396,36 @@ export function loveTrack(uri) {
|
||||
|
||||
export function unloveTrack(uri) {
|
||||
return (dispatch, getState) => {
|
||||
if (getState().core.items[uri] !== undefined) {
|
||||
var track = getState().core.items[uri];
|
||||
if (!track.artists) {
|
||||
dispatch(coreActions.handleException(
|
||||
'Could not unlove LastFM track',
|
||||
track,
|
||||
'Track has no artists',
|
||||
));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const asset = getItem(getState(), uri) || {};
|
||||
if (!asset) {
|
||||
dispatch(coreActions.handleException(
|
||||
'Could not unlove LastFM track',
|
||||
track,
|
||||
'Could not love LastFM track',
|
||||
asset,
|
||||
'Could not find track in index',
|
||||
));
|
||||
return;
|
||||
}
|
||||
if (asset && !asset.artists) {
|
||||
dispatch(coreActions.handleException(
|
||||
'Could not love LastFM track',
|
||||
asset,
|
||||
'Track has no artists',
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
const artist = encodeURIComponent(track.artists[0].name);
|
||||
const params = `method=track.unlove&track=${track.name}&artist=${artist}`;
|
||||
const artist = encodeURIComponent(asset.artists[0].name);
|
||||
const params = `method=track.unlove&track=${asset.name}&artist=${artist}`;
|
||||
sendSignedRequest(dispatch, getState, params)
|
||||
.then(
|
||||
(response) => {
|
||||
() => {
|
||||
dispatch(coreActions.itemLoaded({
|
||||
uri,
|
||||
userloved: false,
|
||||
}));
|
||||
dispatch(uiActions.createNotification({
|
||||
content: <span>Unloved <URILink uri={uri}>{asset ? asset.name : type}</URILink></span>,
|
||||
}));
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
arrayOf,
|
||||
shuffle,
|
||||
} from '../../util/arrays';
|
||||
import { arrayOf } from '../../util/arrays';
|
||||
import {
|
||||
generateGuid,
|
||||
getFromUri,
|
||||
|
||||
Reference in New Issue
Block a user