Standardized ensureLoaded to load assets from index, coldstore or fetch()
This commit is contained in:
@ -9,8 +9,6 @@ class Stream extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
console.log(props);
|
||||
|
||||
if (props.enabled && props.streaming_enabled) {
|
||||
this.start();
|
||||
}
|
||||
@ -28,7 +26,6 @@ class Stream extends React.Component {
|
||||
this.snapstream.play();
|
||||
} else {
|
||||
const protocol = (ssl ? 'wss' : 'ws');
|
||||
console.log(protocol, host, port, username);
|
||||
this.snapstream = new SnapStream(protocol, host, port, 'Iris');
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,12 +65,6 @@ export function clearCurrentTrack() {
|
||||
};
|
||||
}
|
||||
|
||||
export function cachebustHttpStream() {
|
||||
return {
|
||||
type: 'CACHEBUST_HTTP_STREAM',
|
||||
};
|
||||
}
|
||||
|
||||
export function clearStorage() {
|
||||
return {
|
||||
type: 'CLEAR_STORAGE',
|
||||
@ -219,12 +213,6 @@ export function itemsLoaded(items) {
|
||||
export function itemLoaded(item) {
|
||||
return itemsLoaded([item]);
|
||||
}
|
||||
export function unloadItem(uri) {
|
||||
return {
|
||||
type: 'UNLOAD_ITEM',
|
||||
uri,
|
||||
};
|
||||
}
|
||||
|
||||
export function tracksLoaded(tracks) {
|
||||
return {
|
||||
|
||||
@ -30,11 +30,13 @@ const spotifyActions = require('../spotify/actions.js');
|
||||
*
|
||||
* @param {*} Object { store, action, fetch, dependents}
|
||||
*/
|
||||
const ensureItemLoaded = ({
|
||||
const ensureLoaded = ({
|
||||
store,
|
||||
containerName = 'items',
|
||||
action,
|
||||
fetch,
|
||||
dependents = [],
|
||||
fullDependents = [],
|
||||
}) => {
|
||||
const {
|
||||
uri,
|
||||
@ -45,12 +47,33 @@ const ensureItemLoaded = ({
|
||||
} = action;
|
||||
const {
|
||||
core: {
|
||||
items: {
|
||||
[containerName]: {
|
||||
[uri]: item,
|
||||
} = {},
|
||||
} = {},
|
||||
} = store.getState();
|
||||
|
||||
const getMissingDependents = (parent) => {
|
||||
const allDependents = [...dependents, ...fullDependents];
|
||||
if (!parent) return allDependents;
|
||||
if (full) {
|
||||
return allDependents.filter((dep) => parent[dep] === undefined || parent[dep] === null);
|
||||
}
|
||||
return dependents.filter((dep) => parent[dep] === undefined || parent[dep] === null);
|
||||
};
|
||||
|
||||
const getDependentUris = (parent) => {
|
||||
if (!parent) return [];
|
||||
|
||||
return [...dependents, ...fullDependents].reduce(
|
||||
(acc, dependent) => [
|
||||
...acc,
|
||||
...(dependent.match(new RegExp('/(.*)_uri(.*)')) ? parent[dependent] : []),
|
||||
],
|
||||
[],
|
||||
);
|
||||
};
|
||||
|
||||
// Forced refetch bypasses everything
|
||||
if (forceRefetch) {
|
||||
console.info(`Force-refetching "${uri}"`);
|
||||
@ -58,61 +81,51 @@ const ensureItemLoaded = ({
|
||||
return;
|
||||
}
|
||||
|
||||
// Already-loaded asset; check we have all of it's dependents
|
||||
// Item already in our index?
|
||||
if (item) {
|
||||
const loadableDependents = dependents.filter((k) => item[k] && item[k].length > 0);
|
||||
if (!full || (loadableDependents.length === dependents.length)) {
|
||||
console.info(`"${uri}" already in index`);
|
||||
loadableDependents.forEach(
|
||||
if (getMissingDependents(item).length === 0) {
|
||||
console.info(`"${uri}" and all dependents already in index`);
|
||||
store.dispatch(uiActions.stopLoading(uri));
|
||||
|
||||
getDependentUris(item).forEach(
|
||||
(dependent) => store.dispatch(coreActions.loadItems(item[dependent])),
|
||||
);
|
||||
store.dispatch(uiActions.stopLoading(uri));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// What about in the coldstore?
|
||||
localForage.getItem(uri).then((restoredItem) => {
|
||||
if (!restoredItem) {
|
||||
if (!restoredItem || getMissingDependents(restoredItem).length > 0) {
|
||||
fetch();
|
||||
return;
|
||||
}
|
||||
|
||||
const loadableDependents = dependents.filter(
|
||||
(k) => restoredItem[k] && restoredItem[k].length > 0,
|
||||
);
|
||||
console.info(`Restoring "${uri}" from database`);
|
||||
store.dispatch(coreActions.restoreItemsFromColdStore([restoredItem]));
|
||||
|
||||
if (full) {
|
||||
// We already have the dependents of our restored item, so restore them.
|
||||
// We assume that because THIS item is in the coldstore, its dependents
|
||||
// are as well.
|
||||
if (dependents.length && loadableDependents.length === dependents.length) {
|
||||
const dependentUris = loadableDependents.reduce(
|
||||
(acc, dependent) => [...acc, ...restoredItem[dependent]],
|
||||
[],
|
||||
);
|
||||
// We already have the dependents of our restored item, so restore them.
|
||||
// We assume that because THIS item is in the coldstore, its dependents
|
||||
// are as well.
|
||||
const dependentUris = getDependentUris(restoredItem);
|
||||
if (dependentUris.length > 0) {
|
||||
console.info(`Restoring ${dependentUris.length} dependents from database`);
|
||||
|
||||
console.info(`Restoring ${dependentUris.length} dependents from database`);
|
||||
|
||||
const restoreAllDependents = dependentUris.map(
|
||||
(dependentUri) => localForage.getItem(dependentUri),
|
||||
);
|
||||
Promise.all(restoreAllDependents).then(
|
||||
(dependentItems) => {
|
||||
store.dispatch(
|
||||
coreActions.restoreItemsFromColdStore(
|
||||
compact(dependentItems), // Squash nulls (ie items not found in coldstore)
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
fetch();
|
||||
}
|
||||
const restoreAllDependents = dependentUris.map(
|
||||
(dependentUri) => localForage.getItem(dependentUri),
|
||||
);
|
||||
Promise.all(restoreAllDependents).then(
|
||||
(dependentItems) => {
|
||||
store.dispatch(
|
||||
coreActions.restoreItemsFromColdStore(
|
||||
compact(dependentItems), // Squash nulls (ie items not found in coldstore)
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const CoreMiddleware = (function () {
|
||||
return (store) => (next) => (action = {}) => {
|
||||
@ -410,7 +423,7 @@ const CoreMiddleware = (function () {
|
||||
break;
|
||||
}
|
||||
};
|
||||
ensureItemLoaded({
|
||||
ensureLoaded({
|
||||
store,
|
||||
action,
|
||||
fetch,
|
||||
@ -435,11 +448,12 @@ const CoreMiddleware = (function () {
|
||||
break;
|
||||
};
|
||||
};
|
||||
ensureItemLoaded({
|
||||
ensureLoaded({
|
||||
store,
|
||||
action,
|
||||
fetch,
|
||||
dependents: ['tracks'],
|
||||
dependents: ['images'],
|
||||
fullDependents: ['tracks'],
|
||||
});
|
||||
next(action);
|
||||
break;
|
||||
@ -459,11 +473,12 @@ const CoreMiddleware = (function () {
|
||||
break;
|
||||
}
|
||||
};
|
||||
ensureItemLoaded({
|
||||
ensureLoaded({
|
||||
store,
|
||||
action,
|
||||
fetch,
|
||||
dependents: ['tracks', 'albums_uris'],
|
||||
dependents: ['images'],
|
||||
fullDependents: ['tracks', 'albums_uris'],
|
||||
});
|
||||
next(action);
|
||||
break;
|
||||
@ -485,11 +500,12 @@ const CoreMiddleware = (function () {
|
||||
break;
|
||||
}
|
||||
};
|
||||
ensureItemLoaded({
|
||||
ensureLoaded({
|
||||
store,
|
||||
action,
|
||||
fetch,
|
||||
dependents: ['tracks'],
|
||||
dependents: ['images'],
|
||||
fullDependents: ['tracks'],
|
||||
});
|
||||
next(action);
|
||||
break;
|
||||
@ -509,11 +525,11 @@ const CoreMiddleware = (function () {
|
||||
break;
|
||||
}
|
||||
};
|
||||
ensureItemLoaded({
|
||||
ensureLoaded({
|
||||
store,
|
||||
dependents: ['playlists_uris'],
|
||||
action,
|
||||
fetch,
|
||||
fullDependents: ['playlists_uris'],
|
||||
});
|
||||
next(action);
|
||||
break;
|
||||
@ -530,11 +546,11 @@ const CoreMiddleware = (function () {
|
||||
break;
|
||||
}
|
||||
};
|
||||
ensureItemLoaded({
|
||||
ensureLoaded({
|
||||
store,
|
||||
dependents: ['playlists_uris'],
|
||||
action,
|
||||
fetch,
|
||||
fullDependents: ['playlists_uris'],
|
||||
});
|
||||
|
||||
next(action);
|
||||
|
||||
@ -1365,6 +1365,10 @@ export function getPlaylist(uri, { full, forceRefetch, callbackAction }) {
|
||||
...formatPlaylist(response),
|
||||
can_edit: (getState().spotify.me && getState().spotify.me.id === response.owner.id),
|
||||
description,
|
||||
// Remove tracks unless we're looking for the full object. This allows our detector
|
||||
// to accurately identify whether we've loaded *ALL* the tracks. Without this, it
|
||||
// doesn't know if we've loaded all tracks, or just the first page.
|
||||
...(full ? {} : { tracks: null }),
|
||||
}));
|
||||
|
||||
if (full) {
|
||||
|
||||
@ -131,7 +131,7 @@ const getCurrentPusherConnection = function (connections, connectionid) {
|
||||
* @param uri = string
|
||||
* */
|
||||
let uriSource = function (uri) {
|
||||
if (!uri) return false;
|
||||
if (!uri) return '';
|
||||
|
||||
const exploded = `${uri}`.split(':');
|
||||
return exploded[0];
|
||||
@ -143,7 +143,7 @@ let uriSource = function (uri) {
|
||||
* @return string
|
||||
* */
|
||||
const uriType = function (uri) {
|
||||
if (!uri) return null;
|
||||
if (!uri) return '';
|
||||
|
||||
const exploded = `${uri}`.split(':');
|
||||
|
||||
@ -441,7 +441,7 @@ const getIndexedRecords = function (index, uris) {
|
||||
* @param string String
|
||||
* @return String
|
||||
* */
|
||||
const titleCase = function (string) {
|
||||
const titleCase = function (string = '') {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
};
|
||||
|
||||
|
||||
@ -62,12 +62,15 @@ class Queue extends React.Component {
|
||||
|
||||
componentDidMount() {
|
||||
const {
|
||||
uiActions: { setWindowTitle },
|
||||
location: { limit } = {},
|
||||
uiActions: {
|
||||
setWindowTitle,
|
||||
},
|
||||
location: {
|
||||
limit,
|
||||
} = {},
|
||||
} = this.props;
|
||||
if (limit) {
|
||||
this.setState({ limit });
|
||||
}
|
||||
|
||||
if (limit) this.setState({ limit });
|
||||
setWindowTitle(i18n('now_playing.title'));
|
||||
}
|
||||
|
||||
@ -86,7 +89,7 @@ class Queue extends React.Component {
|
||||
} = this.props;
|
||||
|
||||
if (added_from_uri && added_from_uri !== prev_added_from_uri) {
|
||||
loadItem(added_from_uri);
|
||||
loadItem(added_from_uri, { full: false });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user