Loading playlist library with new URI; Starting #600

This commit is contained in:
James Barnsley
2020-09-04 09:21:42 +12:00
parent 6020781be0
commit 6dca4ef475
13 changed files with 579 additions and 415 deletions

View File

@ -160,6 +160,14 @@ export function loadUserPlaylists(uri, force_reload = false) {
};
}
export function loadLibrary(uri, force_reload = false) {
return {
type: 'LOAD_LIBRARY',
uri,
force_reload,
};
}
/**
* Record loaders

View File

@ -4,7 +4,7 @@ import ReactGA from 'react-ga';
import localForage from 'localforage';
import { arrayOf } from '../../util/arrays';
import URILink from '../../components/URILink';
import { uriSource, upgradeSpotifyPlaylistUris, uriType } from '../../util/helpers';
import { uriSource, upgradeSpotifyPlaylistUris, uriType, titleCase } from '../../util/helpers';
import {
formatTracks,
formatTrack,
@ -348,20 +348,14 @@ const CoreMiddleware = (function () {
break;
case 'LOAD_ALBUM':
// Load from Redux store
if (
!action.force_reload
&& store.getState().core.albums[action.uri]
&& store.getState().core.albums[action.uri].tracks_uris) {
if (!action.force_reload && store.getState().core.items[action.uri]) {
console.info(`Loading "${action.uri}" from index`);
break;
}
// Try our cold storage
localForage.getItem(action.uri).then((result) => {
if (result) {
if (result && !action.force_reload) {
console.info(`Loading "${action.uri}" from database`);
store.dispatch(coreActions.restoreFromColdStore(result));
} else {
@ -416,7 +410,7 @@ const CoreMiddleware = (function () {
// Try our cold storage
localForage.getItem(action.uri).then((result) => {
if (result) {
if (result && !action.force_reload) {
console.info(`Loading "${action.uri}" from database`);
store.dispatch(coreActions.restoreFromColdStore(result));
} else {
@ -440,28 +434,39 @@ const CoreMiddleware = (function () {
break;
case 'LOAD_PLAYLIST':
if (
!action.force_reload
&& store.getState().core.playlists[action.uri]
&& store.getState().core.playlists[action.uri].tracks_uris !== undefined
) {
console.info(`Loading "${action.uri}" from index`);
const fetchPlaylist = () => {
switch (uriSource(action.uri)) {
case 'spotify':
store.dispatch(spotifyActions.getPlaylist(action.uri));
if (spotify.me) {
store.dispatch(spotifyActions.following(action.uri));
}
break;
default:
store.dispatch(mopidyActions.getPlaylist(action.uri));
break;
}
};
if (action.force_reload) {
fetchPlaylist();
break;
}
if (store.getState().core.items[action.uri]) {
console.info(`Using "${action.uri}" from index`);
break;
}
switch (uriSource(action.uri)) {
case 'spotify':
store.dispatch(spotifyActions.getPlaylist(action.uri));
if (spotify.me) {
store.dispatch(spotifyActions.following(action.uri));
}
break;
default:
store.dispatch(mopidyActions.getPlaylist(action.uri));
break;
}
localForage.getItem(action.uri).then((result) => {
if (result) {
console.info(`Restoring "${action.uri}" from database`);
store.dispatch(coreActions.restoreFromColdStore(result));
} else {
fetchPlaylist();
}
});
next(action);
break;
@ -514,6 +519,44 @@ const CoreMiddleware = (function () {
next(action);
break;
case 'LOAD_LIBRARY':
const fetchLibrary = () => {
switch (uriSource(action.uri)) {
case 'spotify':
store.dispatch(
spotifyActions[`getLibrary${titleCase(uriType(action.uri))}`](action.uri),
);
break;
default:
store.dispatch(
mopidyActions[`getLibrary${titleCase(uriType(action.uri))}`](action.uri),
);
break;
}
};
if (action.force_reload) {
fetchLibrary();
break;
}
if (store.getState().core.items[action.uri]) {
console.info(`Using "${action.uri}" from index`);
break;
}
localForage.getItem(action.uri).then((result) => {
if (result) {
console.info(`Restoring "${action.uri}" from database`);
store.dispatch(coreActions.restoreFromColdStore(result));
} else {
fetchLibrary();
}
});
next(action);
break;
/**
* Index actions

View File

@ -1600,39 +1600,35 @@ const MopidyMiddleware = (function () {
case 'MOPIDY_GET_LIBRARY_PLAYLISTS':
request(store, 'playlists.asList')
.then((response) => {
// drop in our URI list
const playlist_uris = arrayOf('uri', response);
const playlist_uris_filtered = [];
// Remove any Spotify playlists. These will be handled by our Spotify API
for (var i = 0; i < playlist_uris.length; i++) {
if (uriSource(playlist_uris[i]) != 'spotify') {
playlist_uris_filtered.push(playlist_uris[i]);
}
}
store.dispatch({ type: 'MOPIDY_LIBRARY_PLAYLISTS_LOADED', uris: playlist_uris_filtered });
store.dispatch({ type: 'MOPIDY_LIBRARY_PLAYLISTS_LOADED_ALL' });
const playlist_uris = arrayOf('uri', response).filter(
(uri) => uriSource(uri) !== 'spotify',
);
const libraryPlaylists = [];
// get the full playlist objects
for (var i = 0; i < playlist_uris_filtered.length; i++) {
request(store, 'playlists.lookup', { uri: playlist_uris_filtered[i] })
playlist_uris.forEach((uri, index) => {
request(store, 'playlists.lookup', { uri })
.then((response) => {
const source = uriSource(response.uri);
const playlist = {
libraryPlaylists.push({
type: 'playlist',
name: response.name,
uri: response.uri,
source,
source: uriSource(response.uri),
provider: 'mopidy',
last_modified: response.last_modified,
tracks_total: (response.tracks ? response.tracks.length : 0),
};
tracks: response.tracks,
});
store.dispatch(coreActions.playlistLoaded(playlist));
if (index === playlist_uris.length - 1) {
store.dispatch(coreActions.itemLoaded({
uri: 'mopidy:library:playlists',
items: libraryPlaylists,
}));
}
});
}
});
});
break;

View File

@ -18,6 +18,7 @@ import {
formatArtist,
formatArtists,
formatAlbums,
formatPlaylists,
} from '../../util/format';
import URILink from '../../components/URILink';
import { i18n } from '../../locale';
@ -1403,6 +1404,8 @@ export function getPlaylist(uri) {
request(dispatch, getState, `playlists/${getFromUri('playlistid', uri)}?market=${getState().spotify.country}`)
.then(
(response) => {
let tracks = formatTracks(response.tracks.items);
// convert links in description
let description = null;
if (response.description) {
@ -1412,22 +1415,29 @@ export function getPlaylist(uri) {
description = description.split('<a href="spotify:user:').join('<a href="#' + '/user/spotify:user:');
}
const tracks = formatTracks(response.tracks.items);
const playlist = {
dispatch(coreActions.itemLoaded({
...formatPlaylist(response),
is_completely_loaded: true,
user_uri: response.owner.uri,
tracks_uris: tracks ? arrayOf('uri', tracks) : null,
tracks_more: response.tracks.next,
tracks_total: response.tracks.total,
user: formatUser(response.owner),
tracks,
description,
};
}));
dispatch(coreActions.userLoaded(formatUser(response.owner)));
dispatch(coreActions.tracksLoaded(tracks));
dispatch(coreActions.playlistLoaded(playlist));
const fetchTracks = (endpoint) => request(dispatch, getState, endpoint)
.then((response) => {
tracks = [...tracks, ...formatTracks(response.items)];
if (response.next) {
fetchTracks(response.next);
} else {
dispatch(coreActions.itemLoaded({
uri,
tracks,
}));
}
});
if (response.tracks.next) {
fetchTracks(response.tracks.next);
}
},
(error) => {
dispatch(coreActions.handleException(
@ -1721,6 +1731,23 @@ export function flushLibrary() {
export function getLibraryPlaylists() {
return (dispatch, getState) => {
let libraryPlaylists = [];
const fetchLibraryPlaylists = (endpoint) => request(dispatch, getState, endpoint)
.then((response) => {
libraryPlaylists = [...libraryPlaylists, ...formatPlaylists(response.items)];
console.log('loaded page of playlists', response.items);
if (response.next) {
fetchLibraryPlaylists(response.next);
} else {
dispatch(coreActions.itemLoaded({
uri: 'spotify:library:playlists',
items: libraryPlaylists,
}));
}
});
fetchLibraryPlaylists('me/playlists?limit=50');
/*
const last_run = getState().ui.processes.SPOTIFY_GET_LIBRARY_PLAYLISTS_PROCESSOR;
if (!last_run) {
@ -1732,6 +1759,7 @@ export function getLibraryPlaylists() {
} else if (last_run.status === 'finished' && !getState().spotify.library_playlists_loaded_all) {
dispatch(uiActions.startProcess('SPOTIFY_GET_LIBRARY_PLAYLISTS_PROCESSOR', 'Loading Spotify playlists', { next: 'me/playlists?limit=50' }));
}
*/
};
}