Removing componentWillReceiveProps from base views

This commit is contained in:
James Barnsley
2020-03-11 20:40:20 +13:00
parent b988cf27f8
commit 3e56a3f873
10 changed files with 239 additions and 168 deletions

2
src/js/util/arrays.js Normal file → Executable file
View File

@ -1,4 +1,4 @@
import { uriSource } from './helpers';
/** /**
* Digest an array of objects and pull into simple array of one property * Digest an array of objects and pull into simple array of one property

View File

@ -29,124 +29,162 @@ import {
import { collate } from '../util/format'; import { collate } from '../util/format';
export class Album extends React.Component { export class Album extends React.Component {
componentDidMount() { componentDidMount = () => {
const {
uri,
album,
coreActions: {
loadAlbum,
},
lastfmActions: {
getAlbum,
},
} = this.props;
this.setWindowTitle(); this.setWindowTitle();
this.props.coreActions.loadAlbum(this.props.uri); loadAlbum(uri);
// We already have the album in our index, so it won't fire componentWillReceiveProps // We already have the album in our index, so it won't fire componentWillReceiveProps
if (this.props.album) { if (album) {
if (this.props.album.artists && this.props.album.wiki === undefined) { if (album.artists && album.wiki === undefined) {
this.props.lastfmActions.getAlbum( getAlbum(album.uri, album.artists[0].name, album.name);
this.props.album.uri,
this.props.album.artists[0].name,
this.props.album.name,
);
} }
} }
} }
handleContextMenu(e) { handleContextMenu = (e) => {
const {
uri,
uiActions: {
showContextMenu,
},
} = this.props;
e.preventDefault(); e.preventDefault();
const data = { uris: [this.props.uri] }; const data = { uris: [uri] };
this.props.uiActions.showContextMenu(e, data, 'album', 'click'); showContextMenu(e, data, 'album', 'click');
} }
componentWillReceiveProps(nextProps) { componentDidUpdate = ({
// if our URI has changed, fetch new album uri: prevUri,
if (nextProps.uri != this.props.uri) { album: prevAlbum,
this.props.coreActions.loadAlbum(nextProps.uri); mopidy_connected: prev_mopidy_connected,
}) => {
const {
uri,
album,
mopidy_connected,
coreActions: {
loadAlbum,
},
lastfmActions: {
getAlbum,
},
} = this.props;
// if mopidy has just connected AND we're a local album, go get if (uri !== prevUri) {
} else if (!this.props.mopidy_connected && nextProps.mopidy_connected) { loadAlbum(uri);
if (uriSource(nextProps.uri) != 'spotify') { } else if (!prev_mopidy_connected && mopidy_connected) {
this.props.coreActions.loadAlbum(nextProps.uri); if (uriSource(uri) !== 'spotify') {
loadAlbum(uri);
} }
} }
// We have just received our full album or our album artists // We have just received our full album or our album artists
if ( if ((!prevAlbum && album) || (!prevAlbum.artists && album.artists)) {
(!this.props.album && nextProps.album) if (album.wiki === undefined && album.artists.length > 0) {
|| (!this.props.album.artists && nextProps.album.artists) getAlbum(album.uri, album.artists[0].name, album.name);
) {
if (nextProps.album.wiki === undefined && nextProps.artists.length > 0) {
this.props.lastfmActions.getAlbum(
nextProps.album.uri,
nextProps.album.artists[0].name,
nextProps.album.name,
);
} }
} }
if (!this.props.album && nextProps.album) { if (!prevAlbum && album) this.setWindowTitle(album);
this.setWindowTitle(nextProps.album);
}
} }
setWindowTitle(album = this.props.album) { setWindowTitle = (album = this.props.album) => {
const { uiActions: { setWindowTitle } } = this.props;
if (album) { if (album) {
let artists = ''; let artists = '';
if (album.artists_uris && this.props.artists) { if (album.artists_uris && artists) {
for (let i = 0; i < album.artists_uris.length; i++) { for (let i = 0; i < album.artists_uris.length; i++) {
const uri = album.artists_uris[i]; const uri = album.artists_uris[i];
if (this.props.artists.hasOwnProperty(uri)) { if (artists.hasOwnProperty(uri)) {
if (artists != '') { if (artists != '') {
artists += ', '; artists += ', ';
} }
artists += this.props.artists[uri].name; artists += artists[uri].name;
} }
} }
} }
this.props.uiActions.setWindowTitle( setWindowTitle(`${album.name} by ${artists} (album)`);
`${album.name} by ${artists} (album)`,
);
} else { } else {
this.props.uiActions.setWindowTitle('Album'); setWindowTitle('Album');
} }
} }
handleContextMenu(e) { handleContextMenu = (e) => {
const data = { const { album, uri, uiActions: { showContextMenu } } = this.props;
showContextMenu({
e, e,
context: 'album', context: 'album',
items: [this.props.album], items: [album],
uris: [this.props.uri], uris: [uri],
}; });
this.props.uiActions.showContextMenu(data);
} }
loadMore() { loadMore = () => {
this.props.spotifyActions.getMore( const {
this.props.album.tracks_more, { spotifyActions: {
getMore,
},
album: {
uri,
name,
tracks_more,
} = {},
} = this.props;
getMore(
tracks_more, {
parent_type: 'album', parent_type: 'album',
parent_key: this.props.album.uri, parent_key: uri,
records_type: 'track', records_type: 'track',
}, },
null, null,
{ {
album: { album: {
uri: this.props.album.uri, uri,
name: this.props.album.name, name,
}, },
}, },
); );
} }
play() { play = () => {
this.props.mopidyActions.playURIs([this.props.uri], this.props.uri); const { uri, mopidyActions: { playURIs } } = this.props;
playURIs([uri], uri);
} }
inLibrary() { inLibrary = () => {
const library = `${uriSource(this.props.uri)}_library_albums`; const { uri } = this.props;
return ( const library = `${uriSource(uri)}_library_albums`;
this.props[library] && this.props[library].indexOf(this.props.uri) > -1 return (this.props[library] && this.props[library].indexOf(this.props.uri) > -1);
);
} }
render() { render = () => {
if (!this.props.album) { const {
uri,
album: albumProp,
tracks,
artists,
load_queue,
} = this.props;
if (!albumProp) {
if ( if (
isLoading(this.props.load_queue, [ isLoading(load_queue, [
`spotify_albums/${getFromUri('albumid', this.props.uri)}`, `spotify_albums/${getFromUri('albumid', uri)}`,
]) ])
) { ) {
return <Loader body loading />; return <Loader body loading />;
@ -154,18 +192,13 @@ export class Album extends React.Component {
return ( return (
<ErrorMessage type="not-found" title="Not found"> <ErrorMessage type="not-found" title="Not found">
<p> <p>
Could not find album with URI " {`Could not find album with URI "${encodeURIComponent(uri)}"`}
{encodeURIComponent(this.props.uri)}
"
</p> </p>
</ErrorMessage> </ErrorMessage>
); );
} }
const album = collate(this.props.album, { const album = collate(albumProp, { tracks, artists });
tracks: this.props.tracks,
artists: this.props.artists,
});
if ( if (
!album.tracks_uris !album.tracks_uris
@ -179,7 +212,7 @@ export class Album extends React.Component {
return ( return (
<div className="view album-view content-wrapper preserve-3d"> <div className="view album-view content-wrapper preserve-3d">
<Parallax image={album.images ? album.images.huge : null} blur /> <Parallax image={album.images && album.images.huge} blur />
<div className="thumbnail-wrapper"> <div className="thumbnail-wrapper">
<Thumbnail size="large" glow canZoom images={album.images} /> <Thumbnail size="large" glow canZoom images={album.images} />

View File

@ -39,22 +39,30 @@ class Artist extends React.Component {
this.props.coreActions.loadArtist(this.props.uri); this.props.coreActions.loadArtist(this.props.uri);
} }
componentWillReceiveProps(nextProps) { componentDidUpdate = ({
if (nextProps.uri != this.props.uri) { uri: prevUri,
this.props.coreActions.loadArtist(nextProps.uri); mopidy_connected: prev_mopidy_connected,
} else if (!this.props.mopidy_connected && nextProps.mopidy_connected) { artist: prevArtist,
if (uriSource(this.props.uri) != 'spotify') { }) => {
this.props.coreActions.loadArtist(nextProps.uri); const {
uri,
mopidy_connected,
artist,
coreActions: {
loadArtist,
},
} = this.props;
if (uri !== prevUri) {
loadArtist(uri);
} else if (!prev_mopidy_connected && mopidy_connected) {
if (uriSource(uri) != 'spotify') {
loadArtist(uri);
} }
} }
if (!this.props.artist && nextProps.artist) { if (!prevArtist && artist) this.setWindowTitle(artist);
this.setWindowTitle(nextProps.artist); if (prevUri !== uri && artist) this.setWindowTitle(artist);
}
if (this.props.uri !== nextProps.uri && nextProps.artist) {
this.setWindowTitle(nextProps.artist);
}
} }
setWindowTitle(artist = this.props.artist) { setWindowTitle(artist = this.props.artist) {

View File

@ -47,27 +47,37 @@ class Playlist extends React.Component {
this.props.coreActions.loadPlaylist(this.props.uri); this.props.coreActions.loadPlaylist(this.props.uri);
} }
componentWillReceiveProps(nextProps) { componentDidUpdate = ({
// Follow a URI moved_to instruction uri: prevUri,
if (this.props.playlist && nextProps.playlist && this.props.playlist.moved_to != nextProps.playlist.moved_to) { playlist: prevPlaylist,
this.props.history.push(`/playlist/${encodeURIComponent(nextProps.playlist.moved_to)}`); mopidy_connected: prev_mopidy_connected,
}) => {
const {
uri,
playlist,
mopidy_connected,
coreActions: {
loadPlaylist,
},
history: {
push,
},
} = this.props;
if (prevPlaylist && playlist && prevPlaylist.moved_to !== playlist.moved_to) {
push(`/playlist/${encodeURIComponent(playlist.moved_to)}`);
} }
if (nextProps.uri != this.props.uri) { if (uri !== prevUri) {
this.props.coreActions.loadPlaylist(nextProps.uri); loadPlaylist(uri);
} else if (!this.props.mopidy_connected && nextProps.mopidy_connected) { } else if (!prev_mopidy_connected && mopidy_connected) {
if (uriSource(this.props.uri) != 'spotify') { if (uriSource(uri) !== 'spotify') {
this.props.coreActions.loadPlaylist(nextProps.uri); loadPlaylist(nextProps.uri);
} }
} }
if (!this.props.playlist && nextProps.playlist) { if (!prevPlaylist && playlist) this.setWindowTitle(playlist);
this.setWindowTitle(nextProps.playlist); if (prevUri !== uri && playlist) this.setWindowTitle(playlist);
}
if (this.props.uri !== nextProps.uri && nextProps.playlist) {
this.setWindowTitle(nextProps.playlist);
}
} }
setWindowTitle(playlist = this.props.playlist) { setWindowTitle(playlist = this.props.playlist) {

View File

@ -47,21 +47,22 @@ class Queue extends React.Component {
return nextProps !== this.props; return nextProps !== this.props;
} }
componentWillReceiveProps(nextProps) { componentDidUpdate = ({
const { added_from_uri: next_added_from_uri } = nextProps; added_from_uri: prev_added_from_uri,
const { coreActions, added_from_uri } = this.props; }) => {
const { coreActions: { loadPlaylist }, added_from_uri } = this.props;
if (next_added_from_uri && next_added_from_uri !== added_from_uri) { if (added_from_uri && added_from_uri !== prev_added_from_uri) {
const item_type = uriType(next_added_from_uri); const item_type = uriType(added_from_uri);
switch (item_type) { switch (item_type) {
case 'album': case 'album':
coreActions.loadAlbum(next_added_from_uri); loadAlbum(added_from_uri);
break; break;
case 'artist': case 'artist':
coreActions.loadArtist(next_added_from_uri); loadArtist(added_from_uri);
break; break;
case 'playlist': case 'playlist':
coreActions.loadPlaylist(next_added_from_uri); loadPlaylist(added_from_uri);
break; break;
default: default:
break; break;

View File

@ -16,10 +16,9 @@ class QueueHistory extends React.Component {
this.loadHistory(); this.loadHistory();
} }
componentWillReceiveProps(nextProps) { componentDidUpdate = ({ mopidy_connected: prev_mopidy_connected }) => {
if (!this.props.mopidy_connected && nextProps.mopidy_connected) { const { mopidy_connected } = this.props;
this.loadHistory(nextProps); if (!prev_mopidy_connected && mopidy_connected) this.loadHistory();
}
} }
loadHistory(props = this.props) { loadHistory(props = this.props) {

View File

@ -47,22 +47,29 @@ class Search extends React.Component {
}); });
} }
componentWillReceiveProps(nextProps) { componentDidUpdate = ({
const { type, term } = this.props; type: prevType,
const { type: nextType, term: nextTerm } = nextProps; term: prevTerm,
if (nextType !== type || nextTerm !== term) { mopidy_connected: prev_mopidy_connected,
this.digestUri({ }) => {
type: nextType, const {
term: nextTerm, type: typeProp,
}); term: termProp,
mopidy_connected,
uri_schemes_search_enabled,
} = this.props;
const { type, term } = this.state;
if (prevType !== typeProp || prevTerm !== termProp) {
this.digestUri({ type: typeProp, term: termProp });
} }
// Services came online // Services came online
if (!this.props.mopidy_connected && nextProps.mopidy_connected && nextProps.uri_schemes_search_enabled) { if (!prev_mopidy_connected && mopidy_connected && uri_schemes_search_enabled) {
this.search(this.state.type, this.state.term, 'mopidy'); this.search(type, term, 'mopidy');
if (nextProps.uri_schemes_search_enabled.includes('spotify:')) { if (uri_schemes_search_enabled.includes('spotify:')) {
this.search(this.state.type, this.state.term, 'spotify'); this.search(type, term, 'spotify');
} }
} }
} }

View File

@ -36,18 +36,16 @@ class Settings extends React.Component {
this.props.uiActions.setWindowTitle('Settings'); this.props.uiActions.setWindowTitle('Settings');
} }
componentWillReceiveProps(nextProps) { componentDidUpdate = () => {
let changed = false; const { pusher: { username } } = this.props;
const { state } = this; const { pusher_username, input_in_focus } = this.state;
let new_username = null;
if (nextProps.pusher.username && nextProps.pusher.username != this.state.pusher_username && this.state.input_in_focus != 'pusher_username') { if (username && username !== pusher_username && input_in_focus !== 'pusher_username') {
state.pusher_username = nextProps.pusher.username; new_username = username;
changed = true;
} }
if (changed) { if (new_username) this.setState({ pusher_username: new_username });
this.setState(state);
}
} }
resetAllSettings() { resetAllSettings() {

View File

@ -47,40 +47,45 @@ class Track extends React.Component {
this.props.uiActions.showContextMenu(e, data, 'track', 'click'); this.props.uiActions.showContextMenu(e, data, 'track', 'click');
} }
componentWillReceiveProps(nextProps) { componentDidUpdate = ({
uri: prevUri,
track: prevTrack,
mopidy_connected: prev_mopidy_connected,
}) => {
const {
uri,
track,
genius_authorized,
lastfm_authorized,
mopidy_connected,
coreActions: {
loadTrack,
},
geniusActions: {
findTrackLyrics,
},
lastfmActions: {
getTrack,
},
} = this.props;
// if our URI has changed, fetch new track // if our URI has changed, fetch new track
if (nextProps.uri != this.props.uri) { if (prevUri !== uri) {
this.props.coreActions.loadTrack(nextProps.uri); loadTrack(uri);
if (genius_authorized && track.artists) findTrackLyrics(track);
if (nextProps.genius_authorized && nextProps.tracks.artists) {
this.props.geniusActions.findTrackLyrics(nextProps.track);
}
// if mopidy has just connected AND we're not a Spotify track, go get // if mopidy has just connected AND we're not a Spotify track, go get
} else if (!this.props.mopidy_connected && nextProps.mopidy_connected) { } else if (!prev_mopidy_connected && mopidy_connected) {
if (helpers.uriSource(this.props.uri) != 'spotify') { if (uriSource(uri) !== 'spotify') loadTrack(uri);
this.props.coreActions.loadTrack(nextProps.uri);
}
} }
// We have just received our full track or our track artists // We have just received our full track or our track artists
if ((!this.props.track && nextProps.track) || (!this.props.track.artists && nextProps.track.artists)) { if ((!prevTrack && track) || (!prevTrack.artists && track.artists)) {
this.setWindowTitle(nextProps.track); this.setWindowTitle(track);
if (lastfm_authorized) getTrack(track.uri);
// Ready to load LastFM if (genius_authorized && !track.lyrics_results) findTrackLyrics(track);
if (nextProps.lastfm_authorized) {
this.props.lastfmActions.getTrack(nextProps.track.uri);
}
// Ready to load lyrics
if (nextProps.genius_authorized && !nextProps.track.lyrics_results) {
this.props.geniusActions.findTrackLyrics(nextProps.track);
}
} }
if (!this.props.track && nextProps.track) { if (!prevTrack && track) this.setWindowTitle(track);
this.setWindowTitle(nextProps.track);
}
} }
setWindowTitle(track = this.props.track) { setWindowTitle(track = this.props.track) {

View File

@ -28,15 +28,25 @@ class User extends React.Component {
this.props.coreActions.loadUserPlaylists(this.props.uri); this.props.coreActions.loadUserPlaylists(this.props.uri);
} }
componentWillReceiveProps(nextProps) { componentDidUpdate = ({
if (nextProps.uri != this.props.uri) { uri: prevUri,
this.props.coreActions.loadUser(nextProps.uri); user: prevUser,
this.props.coreActions.loadUserPlaylists(this.props.uri); }) => {
const {
uri,
user,
coreActions: {
loadUser,
loadUserPlaylists,
},
} = this.props;
if (prevUri !== uri) {
loadUser(uri);
loadUserPlaylists(uri);
} }
if (!this.props.user && nextProps.user) { if (!prevUser && user) this.setWindowTitle(user);
this.setWindowTitle(nextProps.user);
}
} }
setWindowTitle(user = this.props.user) { setWindowTitle(user = this.props.user) {