Universal loadedMore for lazy-loading assets

This commit is contained in:
James Barnsley
2017-11-09 21:04:45 +13:00
parent 891dc2af7a
commit e2dbbac98b
7 changed files with 136 additions and 20 deletions

View File

@ -221,6 +221,16 @@ export function getLibraryArtists(){
* Assets loaded
**/
export function loadedMore(parent_type, parent_key, records_type, records_data){
return {
type: 'LOADED_MORE',
parent_type: parent_type,
parent_key: parent_key,
records_type: records_type,
records_data: records_data
}
}
export function tracksLoaded(tracks){
return {
type: 'TRACKS_LOADED',

View File

@ -220,7 +220,6 @@ const CoreMiddleware = (function(){
break;
case 'MOPIDY_TLTRACKS':
var core = store.getState().core;
var tracklist = []
for (var i = 0; i < action.data.length; i++){
@ -484,19 +483,7 @@ const CoreMiddleware = (function(){
}
if (playlists[playlist.uri] !== undefined){
var existing_playlist = playlists[playlist.uri];
if (existing_playlist.tracks && playlist.tracks){
var tracks = [...existing_playlist.tracks, ...playlist.tracks];
} else if (existing_playlist.tracks){
var tracks = existing_playlist.tracks;
} else if (playlist.tracks){
var tracks = playlist.tracks;
} else {
var tracks = [];
}
playlist = Object.assign({tracks: tracks}, existing_playlist, playlist);
playlist = Object.assign({}, playlists[playlist.uri], playlist);
}
// Load our tracks
@ -527,7 +514,7 @@ const CoreMiddleware = (function(){
break;
case 'USERS_LOADED':
var users = Object.assign([], core.users);
var users = Object.assign({}, core.users);
for (var i = 0; i < action.users.length; i++){
var user = Object.assign({}, action.users[i]);
@ -548,6 +535,63 @@ const CoreMiddleware = (function(){
next(action);
break;
/**
* Loaded more linked assets
* Often fired during lazy-loading or async asset grabbing.
* We link the parent to these indexed records by {type}s_uris
**/
case 'LOADED_MORE':
var parent_type_plural = action.parent_type+'s';
var parent_index = Object.assign({}, core[action.parent_type+'s']);
var parent = Object.assign({}, parent_index[action.parent_key]);
if (action.records_data.items !== undefined){
var records = action.records_data.items;
} else if (action.records_data.tracks !== undefined){
var records = action.records_data.tracks;
} else if (action.records_data.artists !== undefined){
var records = action.records_data.artists;
} else if (action.records_data.albums !== undefined){
var records = action.records_data.albums;
} else if (action.records_data.playlists !== undefined){
var records = action.records_data.playlists;
} else {
var records = action.records_data;
}
if (action.records_type == 'track'){
records = helpers.formatTracks(records);
}
var records_type_plural = action.records_type+'s';
var records_index = Object.assign({});
var records_uris = helpers.arrayOf('uri', records);
// Append our records_uris array with our new records
var uris = [...parent[records_type_plural+'_uris'], ...records_uris];
parent[records_type_plural+'_uris'] = uris;
if (action.records_data.next !== undefined){
parent[records_type_plural+'_more'] = action.records_data.next;
}
// Parent loaded (well, changed)
var parent_action = {
type: parent_type_plural.toUpperCase()+'_LOADED'
};
parent_action[parent_type_plural] = [parent];
store.dispatch(parent_action);
// Records loaded
var records_action = {
type: records_type_plural.toUpperCase()+'_LOADED'
};
records_action[records_type_plural] = records;
store.dispatch(records_action);
next(action);
break;
// This action is irrelevant to us, pass it on to the next middleware
default:
return next(action)

View File

@ -505,6 +505,40 @@ export function getURL(url, action_name, key = false){
}
}
export function loadMore(url, loaded_more_action = null, custom_action = null){
return (dispatch, getState) => {
sendRequest(dispatch, getState, url)
.then(
response => {
if (loaded_more_action){
dispatch(coreActions.loadedMore(
loaded_more_action.parent_type,
loaded_more_action.parent_key,
loaded_more_action.records_type,
response
));
} else if (custom_action){
dispatch({
type: custom_action.type,
key: custom_action.key,
data: response
});
} else {
dispatch(coreActions.handleException(
'No callback handler for loading more items'
));
}
},
error => {
dispatch(coreActions.handleException(
'Could not load more '+callback_action.parent_type+' '+callback_action.records_type+'s',
error
));
}
);
}
}
export function clearSearchResults(){
return {
type: 'SPOTIFY_CLEAR_SEARCH_RESULTS'

View File

@ -85,7 +85,14 @@ class Album extends React.Component{
}
loadMore(){
this.props.spotifyActions.getURL(this.props.album.tracks_more, 'SPOTIFY_ALBUM_LOADED_MORE' );
this.props.spotifyActions.loadMore(
this.props.album.tracks_more,
{
parent_type: 'album',
parent_key: this.props.album.uri,
records_type: 'track'
}
);
}
play(){

View File

@ -74,7 +74,14 @@ class Playlist extends React.Component{
}
loadMore(){
this.props.spotifyActions.getURL(this.props.playlist.tracks_more, 'PLAYLIST_LOADED_MORE_TRACKS', this.props.playlist.uri );
this.props.spotifyActions.loadMore(
this.props.playlist.tracks_more,
{
parent_type: 'playlist',
parent_key: this.props.playlist.uri,
records_type: 'track'
}
);
}
play(){
@ -223,7 +230,7 @@ const mapStateToProps = (state, ownProps) => {
slim_mode: state.ui.slim_mode,
load_queue: state.ui.load_queue,
tracks: state.core.tracks,
playlist: (state.core.playlists && state.core.playlists[uri] !== undefined ? state.core.playlists[uri] : false ),
playlist: (state.core.playlists[uri] !== undefined ? state.core.playlists[uri] : false ),
spotify_library_playlists: state.spotify.library_playlists,
local_library_playlists: state.mopidy.library_playlists,
mopidy_connected: state.mopidy.connected,

View File

@ -30,7 +30,14 @@ class DiscoverCategory extends React.Component{
}
loadMore(){
this.props.spotifyActions.getURL(this.props.category.playlists_more, 'SPOTIFY_CATEGORY_PLAYLISTS_LOADED', 'category:'+this.props.params.id );
this.props.spotifyActions.loadMore(
this.props.category.playlists_more,
null,
{
type: 'SPOTIFY_CATEGORY_PLAYLISTS_LOADED',
key: 'category:'+this.props.params.id
}
);
}
render(){

View File

@ -27,7 +27,14 @@ class DiscoverNewReleases extends React.Component{
}
loadMore(){
this.props.spotifyActions.getURL(this.props.new_releases_more, 'SPOTIFY_NEW_RELEASES_LOADED');
this.props.spotifyActions.loadMore(
this.props.new_releases_more,
null,
{
type: 'SPOTIFY_NEW_RELEASES_LOADED',
key: null
}
);
}
playAlbum(e,album){