Everything goes through loadItem; Options now provide 'full' switch for full asset on demand

This commit is contained in:
James Barnsley
2020-09-09 21:30:47 +12:00
parent 3e4fdd2c2f
commit a4fd0cd8e5
14 changed files with 321 additions and 308 deletions

View File

@ -107,75 +107,71 @@ export function updateColdStore(items) {
* relevant service to load the record - all from one neat package.
* */
export function loadItems(uris, forceRefetch = false, callbackAction = null) {
export function loadItems(uris, options = {}) {
return {
type: 'LOAD_ITEMS',
uris,
forceRefetch,
callbackAction,
options,
};
}
export function loadItem(uri, forceRefetch = false, callbackAction) {
return loadItems([uri], forceRefetch, callbackAction);
export function loadItem(uri, options = {}) {
return loadItems([uri], options);
}
export function loadTrack(uri, forceRefetch = false) {
export function loadTrack(uri, options = {}) {
return {
type: 'LOAD_TRACK',
uri,
forceRefetch,
options,
};
}
export function loadAlbum(uri, forceRefetch = false, callbackAction) {
export function loadAlbum(uri, options = {}) {
return {
type: 'LOAD_ALBUM',
uri,
forceRefetch,
callbackAction,
options,
};
}
export function loadArtist(uri, forceRefetch = false, callbackAction) {
export function loadArtist(uri, options = {}) {
return {
type: 'LOAD_ARTIST',
uri,
forceRefetch,
callbackAction,
options,
};
}
export function loadPlaylist(uri, forceRefetch = false, callbackAction) {
export function loadPlaylist(uri, options = {}) {
return {
type: 'LOAD_PLAYLIST',
uri,
forceRefetch,
callbackAction,
options,
};
}
export function loadUser(uri, forceRefetch = false) {
export function loadUser(uri, options = {}) {
return {
type: 'LOAD_USER',
uri,
forceRefetch,
options,
};
}
export function loadUserPlaylists(uri, forceRefetch = false) {
export function loadUserPlaylists(uri, options) {
return {
type: 'LOAD_USER_PLAYLISTS',
uri,
forceRefetch,
options,
};
}
export function loadLibrary(uri, forceRefetch = false) {
export function loadLibrary(uri, options = {}) {
return {
type: 'LOAD_LIBRARY',
uri,
forceRefetch,
options,
};
}

View File

@ -318,8 +318,7 @@ const CoreMiddleware = (function () {
store.dispatch({
type: `LOAD_${uriType(uri).toUpperCase()}`,
uri,
forceRefetch: action.forceRefetch,
callbackAction: action.callbackAction,
options: action.options,
});
});
break;
@ -328,7 +327,7 @@ const CoreMiddleware = (function () {
const fetchTrack = () => {
switch (uriSource(action.uri)) {
case 'spotify':
store.dispatch(spotifyActions.getTrack(action.uri, action.forceRefetch));
store.dispatch(spotifyActions.getTrack(action.uri, action.options));
if (spotify.me) {
store.dispatch(spotifyActions.following(action.uri));
@ -341,7 +340,7 @@ const CoreMiddleware = (function () {
}
};
if (action.forceRefetch) {
if (action.options.forceRefetch) {
console.info(`Force-refetching "${action.uri}"`);
fetchTrack();
break;
@ -375,7 +374,7 @@ const CoreMiddleware = (function () {
const fetchAlbum = () => {
switch (uriSource(action.uri)) {
case 'spotify':
store.dispatch(spotifyActions.getAlbum(action.uri, action.forceRefetch));
store.dispatch(spotifyActions.getAlbum(action.uri, action.options));
if (spotify.me) {
store.dispatch(spotifyActions.following(action.uri));
@ -388,14 +387,14 @@ const CoreMiddleware = (function () {
};
};
if (action.forceRefetch) {
if (action.options.forceRefetch) {
console.info(`Force-refetching "${action.uri}"`);
fetchAlbum();
break;
}
if (
store.getState().core.items[action.uri]
&& store.getState().core.items[action.uri].tracks
&& (!action.options.full || store.getState().core.items[action.uri].tracks)
) {
console.info(`Using "${action.uri}" from index`);
break;
@ -422,7 +421,7 @@ const CoreMiddleware = (function () {
const fetchArtist = () => {
switch (uriSource(action.uri)) {
case 'spotify':
store.dispatch(spotifyActions.getArtist(action.uri, true, action.forceRefetch));
store.dispatch(spotifyActions.getArtist(action.uri, action.options));
if (spotify.me) {
store.dispatch(spotifyActions.following(action.uri));
@ -435,16 +434,21 @@ const CoreMiddleware = (function () {
}
};
if (action.forceRefetch) {
if (action.options.forceRefetch) {
console.info(`Force-refetching "${action.uri}"`);
fetchArtist();
break;
}
if (
store.getState().core.items[action.uri]
&& store.getState().core.items[action.uri].tracks
&& store.getState().core.items[action.uri].albums_uris
&& store.getState().core.items[action.uri].images
&& (
!action.options.full
|| (
store.getState().core.items[action.uri].tracks
&& store.getState().core.items[action.uri].albums_uris
&& store.getState().core.items[action.uri].images
)
)
) {
console.info(`Using "${action.uri}" from index`);
break;
@ -452,25 +456,17 @@ const CoreMiddleware = (function () {
localForage.getItem(action.uri).then((artist) => {
if (artist) {
console.info(`Restoring "${action.uri}" and ${artist.albums_uris.length} albums from database`);
console.info(`Restoring "${action.uri}" and ${artist.albums_uris ? artist.albums_uris.length : 0} albums from database`);
store.dispatch(coreActions.restoreItemsFromColdStore([artist]));
const promises = artist.albums_uris.map((albumUri) => localForage.getItem(albumUri));
Promise.all(promises).then(
(albums) => store.dispatch(coreActions.restoreItemsFromColdStore(compact(albums))),
);
if (artist.albums_uris) {
const promises = artist.albums_uris.map((albumUri) => localForage.getItem(albumUri));
Promise.all(promises).then(
(albums) => store.dispatch(coreActions.restoreItemsFromColdStore(compact(albums))),
);
}
store.dispatch(coreActions.restoreLibraryFromColdStore(artist));
} else {
fetchArtist();
}
});
localForage.getItem(action.uri).then((result) => {
if (result) {
console.info(`Restoring "${action.uri}" from database`);
store.dispatch(coreActions.restoreItemsFromColdStore([result]));
if (!result.tracks || !result.albums_uris || !result.images) {
if (action.options.full && (!artist.tracks || !artist.albums_uris || !artist.images)) {
fetchArtist();
}
} else {
@ -485,7 +481,7 @@ const CoreMiddleware = (function () {
const fetchPlaylist = () => {
switch (uriSource(action.uri)) {
case 'spotify':
store.dispatch(spotifyActions.getPlaylist(action.uri, action.forceRefetch));
store.dispatch(spotifyActions.getPlaylist(action.uri, action.options));
if (spotify.me) {
store.dispatch(spotifyActions.following(action.uri));
@ -498,14 +494,17 @@ const CoreMiddleware = (function () {
}
};
if (action.forceRefetch) {
if (action.options.forceRefetch) {
console.info(`Force-refetching "${action.uri}"`);
fetchPlaylist();
break;
}
if (
store.getState().core.items[action.uri]
&& store.getState().core.items[action.uri].tracks
&& (
!action.options.full
|| store.getState().core.items[action.uri].tracks
)
) {
console.info(`Using "${action.uri}" from index`);
break;
@ -515,7 +514,7 @@ const CoreMiddleware = (function () {
if (result) {
console.info(`Restoring "${action.uri}" from database`);
store.dispatch(coreActions.restoreItemsFromColdStore([result]));
if (!result.tracks) {
if (!action.options.full || !result.tracks) {
fetchPlaylist();
}
} else {
@ -528,7 +527,7 @@ const CoreMiddleware = (function () {
case 'LOAD_USER':
if (
!action.forceRefetch
!action.options.forceRefetch
&& store.getState().core.users[action.uri]
&& store.getState().core.users[action.uri].playlists_uris) {
console.info(`Loading "${action.uri}" from index`);
@ -554,7 +553,7 @@ const CoreMiddleware = (function () {
case 'LOAD_USER_PLAYLISTS':
if (
!action.forceRefetch
!action.options.forceRefetch
&& store.getState().core.users[action.uri]
&& store.getState().core.users[action.uri].playlists_uris) {
console.info(`Loading "${action.uri}" playlists from index`);
@ -595,7 +594,7 @@ const CoreMiddleware = (function () {
}
};
if (action.forceRefetch) {
if (action.options.forceRefetch) {
console.info(`Force-refetching "${action.uri}"`);
fetchLibrary();
break;

View File

@ -665,7 +665,7 @@ const MopidyMiddleware = (function () {
break;
}
store.dispatch(
coreActions.loadPlaylist(
coreActions.loadItem(
action.uri,
false,
{
@ -690,7 +690,7 @@ const MopidyMiddleware = (function () {
break;
}
store.dispatch(
coreActions.loadPlaylist(
coreActions.loadItem(
action.uri,
false,
{

View File

@ -1035,7 +1035,7 @@ export function getGenres() {
* @param uri string
* @param full boolean (whether we want a full artist object)
* */
export function getArtist(uri, full = false, forceRefetch = false) {
export function getArtist(uri, { full, forceRefetch }) {
return (dispatch, getState) => {
const endpoint = `artists/${getFromUri('artistid', uri)}${forceRefetch ? `?refetch=${Date.now()}` : ''}`;
request(dispatch, getState, endpoint, 'GET', false, true)
@ -1203,7 +1203,7 @@ export function getUserPlaylists(uri) {
*
* @oaram uri string
* */
export function getAlbum(uri, forceRefetch) {
export function getAlbum(uri, { full, forceRefetch }) {
return (dispatch, getState) => {
const endpoint = `albums/${getFromUri('albumid', uri)}${forceRefetch ? `?refetch=${Date.now()}` : ''}`;
request(dispatch, getState, endpoint)
@ -1211,25 +1211,26 @@ export function getAlbum(uri, forceRefetch) {
(response) => {
dispatch(coreActions.itemLoaded({
...formatAlbum(response),
tracks: formatTracks(response.tracks.items),
}));
let tracks = formatTracks(response.tracks.items);
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 (full) {
let tracks = formatTracks(response.tracks.items);
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);
if (response.tracks.next) {
fetchTracks(response.tracks.next);
}
}
},
(error) => {
@ -1349,7 +1350,7 @@ export function savePlaylist(uri, name, description, is_public, is_collaborative
};
}
export function getPlaylist(uri, forceRefetch = false, callbackAction = null) {
export function getPlaylist(uri, { full, forceRefetch, callbackAction }) {
return (dispatch, getState) => {
const endpoint = `playlists/${getFromUri('playlistid', uri)}?market=${getState().spotify.country}${forceRefetch ? `&refetch=${Date.now()}` : ''}`;
request(dispatch, getState, endpoint)
@ -1369,49 +1370,50 @@ export function getPlaylist(uri, forceRefetch = false, callbackAction = null) {
dispatch(coreActions.itemLoaded({
...formatPlaylist(response),
can_edit: (getState().spotify.me && getState().spotify.me.id === response.owner.id),
tracks,
description,
}));
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 (full) {
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 (callbackAction) {
switch (callbackAction.name) {
case 'enqueue':
dispatch(mopidyActions.enqueueURIs(
arrayOf('uri', tracks),
uri,
callbackAction.play_next,
callbackAction.at_position,
callbackAction.offset,
));
break;
case 'play':
dispatch(mopidyActions.playURIs(
arrayOf('uri', tracks),
uri,
callbackAction.shuffle,
));
break;
default:
break;
if (callbackAction) {
switch (callbackAction.name) {
case 'enqueue':
dispatch(mopidyActions.enqueueURIs(
arrayOf('uri', tracks),
uri,
callbackAction.play_next,
callbackAction.at_position,
callbackAction.offset,
));
break;
case 'play':
dispatch(mopidyActions.playURIs(
arrayOf('uri', tracks),
uri,
callbackAction.shuffle,
));
break;
default:
break;
}
}
}
}
});
});
if (response.tracks.next) {
fetchTracks(response.tracks.next);
}
if (response.tracks.next) {
fetchTracks(response.tracks.next);
}
};
},
(error) => {
dispatch(coreActions.handleException(
@ -1722,7 +1724,11 @@ export function getLibraryPlaylists(forceRefetch) {
const fetchLibraryPlaylists = (endpoint) => request(dispatch, getState, endpoint)
.then((response) => {
const items = response.items.map(
(item) => ({ ...item, in_library: true }),
(item) => ({
...item,
in_library: true,
can_edit: (getState().spotify.me && item.owner.id === getState().spotify.me.id),
}),
);
libraryItems = [...libraryItems, ...formatPlaylists(items)];
if (response.next) {