Standardized ensureLoaded to load assets from index, coldstore or fetch()

This commit is contained in:
James Barnsley
2020-10-06 20:43:47 +13:00
parent 4e0a5a7f7d
commit 81399d6d72
10 changed files with 181 additions and 170 deletions

View File

@ -115457,7 +115457,6 @@ var Stream = /*#__PURE__*/function (_React$Component) {
_this.snapstream.play();
} else {
var protocol = ssl ? 'wss' : 'ws';
console.log(protocol, host, port, username);
_this.snapstream = new _SnapStream__WEBPACK_IMPORTED_MODULE_4__["SnapStream"](protocol, host, port, 'Iris');
}
});
@ -115489,8 +115488,6 @@ var Stream = /*#__PURE__*/function (_React$Component) {
return null;
});
console.log(props);
if (props.enabled && props.streaming_enabled) {
_this.start();
}
@ -117124,7 +117121,7 @@ module.exports = JSON.parse("{\"name\":\"Svenska\",\"errors\":{\"uri_not_found\"
/*!*****************************************!*\
!*** ./src/js/services/core/actions.js ***!
\*****************************************/
/*! exports provided: startSearch, handleException, debugResponse, set, clearCurrentTrack, cachebustHttpStream, clearStorage, restoreItemsFromColdStore, restoreLibraryFromColdStore, updateColdStore, loadItems, loadItem, loadTrack, loadAlbum, loadArtist, loadPlaylist, loadUser, loadUserPlaylists, loadLibrary, addToLibrary, removeFromLibrary, libraryLoaded, unloadLibrary, itemsLoaded, itemLoaded, unloadItem, tracksLoaded, trackLoaded, artistsLoaded, albumsLoaded, albumLoaded, playlistsLoaded, playlistLoaded, usersLoaded, userLoaded, userPlaylistsLoaded, loadedMore, removeItem, viewDataLoaded, reorderPlaylistTracks, savePlaylist, createPlaylist, deletePlaylist, removeTracksFromPlaylist, addTracksToPlaylist, getLibraryPlaylists, getLibraryAlbums, getLibraryArtists, addPinned, removePinned, updatePinned, updatePinnedUri */
/*! exports provided: startSearch, handleException, debugResponse, set, clearCurrentTrack, clearStorage, restoreItemsFromColdStore, restoreLibraryFromColdStore, updateColdStore, loadItems, loadItem, loadTrack, loadAlbum, loadArtist, loadPlaylist, loadUser, loadUserPlaylists, loadLibrary, addToLibrary, removeFromLibrary, libraryLoaded, unloadLibrary, itemsLoaded, itemLoaded, tracksLoaded, trackLoaded, artistsLoaded, albumsLoaded, albumLoaded, playlistsLoaded, playlistLoaded, usersLoaded, userLoaded, userPlaylistsLoaded, loadedMore, removeItem, viewDataLoaded, reorderPlaylistTracks, savePlaylist, createPlaylist, deletePlaylist, removeTracksFromPlaylist, addTracksToPlaylist, getLibraryPlaylists, getLibraryAlbums, getLibraryArtists, addPinned, removePinned, updatePinned, updatePinnedUri */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@ -117134,7 +117131,6 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "debugResponse", function() { return debugResponse; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "set", function() { return set; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clearCurrentTrack", function() { return clearCurrentTrack; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cachebustHttpStream", function() { return cachebustHttpStream; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clearStorage", function() { return clearStorage; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "restoreItemsFromColdStore", function() { return restoreItemsFromColdStore; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "restoreLibraryFromColdStore", function() { return restoreLibraryFromColdStore; });
@ -117154,7 +117150,6 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unloadLibrary", function() { return unloadLibrary; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "itemsLoaded", function() { return itemsLoaded; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "itemLoaded", function() { return itemLoaded; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unloadItem", function() { return unloadItem; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tracksLoaded", function() { return tracksLoaded; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "trackLoaded", function() { return trackLoaded; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "artistsLoaded", function() { return artistsLoaded; });
@ -117250,11 +117245,6 @@ function clearCurrentTrack() {
type: 'CLEAR_CURRENT_TRACK'
};
}
function cachebustHttpStream() {
return {
type: 'CACHEBUST_HTTP_STREAM'
};
}
function clearStorage() {
return {
type: 'CLEAR_STORAGE'
@ -117395,12 +117385,6 @@ function itemsLoaded(items) {
function itemLoaded(item) {
return itemsLoaded([item]);
}
function unloadItem(uri) {
return {
type: 'UNLOAD_ITEM',
uri: uri
};
}
function tracksLoaded(tracks) {
return {
type: 'TRACKS_LOADED',
@ -117736,12 +117720,16 @@ var spotifyActions = __webpack_require__(/*! ../spotify/actions.js */ "./src/js/
*/
var ensureItemLoaded = function ensureItemLoaded(_ref) {
var ensureLoaded = function ensureLoaded(_ref) {
var store = _ref.store,
_ref$containerName = _ref.containerName,
containerName = _ref$containerName === void 0 ? 'items' : _ref$containerName,
action = _ref.action,
fetch = _ref.fetch,
_ref$dependents = _ref.dependents,
dependents = _ref$dependents === void 0 ? [] : _ref$dependents;
dependents = _ref$dependents === void 0 ? [] : _ref$dependents,
_ref$fullDependents = _ref.fullDependents,
fullDependents = _ref$fullDependents === void 0 ? [] : _ref$fullDependents;
var uri = action.uri,
_action$options = action.options,
forceRefetch = _action$options.forceRefetch,
@ -117751,63 +117739,74 @@ var ensureItemLoaded = function ensureItemLoaded(_ref) {
_store$getState$core = _store$getState.core;
_store$getState$core = _store$getState$core === void 0 ? {} : _store$getState$core;
var _store$getState$core$ = _store$getState$core.items;
var _store$getState$core$ = _store$getState$core[containerName];
_store$getState$core$ = _store$getState$core$ === void 0 ? {} : _store$getState$core$;
var item = _store$getState$core$[uri]; // Forced refetch bypasses everything
var item = _store$getState$core$[uri];
var getMissingDependents = function getMissingDependents(parent) {
var allDependents = [].concat(_toConsumableArray(dependents), _toConsumableArray(fullDependents));
if (!parent) return allDependents;
if (full) {
return allDependents.filter(function (dep) {
return parent[dep] === undefined || parent[dep] === null;
});
}
return dependents.filter(function (dep) {
return parent[dep] === undefined || parent[dep] === null;
});
};
var getDependentUris = function getDependentUris(parent) {
if (!parent) return [];
return [].concat(_toConsumableArray(dependents), _toConsumableArray(fullDependents)).reduce(function (acc, dependent) {
return [].concat(_toConsumableArray(acc), _toConsumableArray(dependent.match(new RegExp('/(.*)_uri(.*)')) ? parent[dependent] : []));
}, []);
}; // Forced refetch bypasses everything
if (forceRefetch) {
console.info("Force-refetching \"".concat(uri, "\""));
fetch();
return;
} // Already-loaded asset; check we have all of it's dependents
} // Item already in our index?
if (item) {
var loadableDependents = dependents.filter(function (k) {
return item[k] && item[k].length > 0;
});
if (!full || loadableDependents.length === dependents.length) {
console.info("\"".concat(uri, "\" already in index"));
loadableDependents.forEach(function (dependent) {
if (getMissingDependents(item).length === 0) {
console.info("\"".concat(uri, "\" and all dependents already in index"));
store.dispatch(uiActions.stopLoading(uri));
getDependentUris(item).forEach(function (dependent) {
return store.dispatch(coreActions.loadItems(item[dependent]));
});
store.dispatch(uiActions.stopLoading(uri));
return;
}
}
} // What about in the coldstore?
localforage__WEBPACK_IMPORTED_MODULE_2___default.a.getItem(uri).then(function (restoredItem) {
if (!restoredItem) {
if (!restoredItem || getMissingDependents(restoredItem).length > 0) {
fetch();
return;
}
var loadableDependents = dependents.filter(function (k) {
return restoredItem[k] && restoredItem[k].length > 0;
});
console.info("Restoring \"".concat(uri, "\" from database"));
store.dispatch(coreActions.restoreItemsFromColdStore([restoredItem]));
store.dispatch(coreActions.restoreItemsFromColdStore([restoredItem])); // 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 (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) {
var dependentUris = loadableDependents.reduce(function (acc, dependent) {
return [].concat(_toConsumableArray(acc), _toConsumableArray(restoredItem[dependent]));
}, []);
console.info("Restoring ".concat(dependentUris.length, " dependents from database"));
var restoreAllDependents = dependentUris.map(function (dependentUri) {
return localforage__WEBPACK_IMPORTED_MODULE_2___default.a.getItem(dependentUri);
});
Promise.all(restoreAllDependents).then(function (dependentItems) {
store.dispatch(coreActions.restoreItemsFromColdStore(Object(lodash__WEBPACK_IMPORTED_MODULE_3__["compact"])(dependentItems) // Squash nulls (ie items not found in coldstore)
));
});
} else {
fetch();
}
var dependentUris = getDependentUris(restoredItem);
if (dependentUris.length > 0) {
console.info("Restoring ".concat(dependentUris.length, " dependents from database"));
var restoreAllDependents = dependentUris.map(function (dependentUri) {
return localforage__WEBPACK_IMPORTED_MODULE_2___default.a.getItem(dependentUri);
});
Promise.all(restoreAllDependents).then(function (dependentItems) {
store.dispatch(coreActions.restoreItemsFromColdStore(Object(lodash__WEBPACK_IMPORTED_MODULE_3__["compact"])(dependentItems) // Squash nulls (ie items not found in coldstore)
));
});
}
});
};
@ -118165,7 +118164,7 @@ var CoreMiddleware = function () {
}
};
ensureItemLoaded({
ensureLoaded({
store: store,
action: action,
fetch: _fetch,
@ -118196,11 +118195,12 @@ var CoreMiddleware = function () {
;
};
ensureItemLoaded({
ensureLoaded({
store: store,
action: action,
fetch: _fetch2,
dependents: ['tracks']
dependents: ['images'],
fullDependents: ['tracks']
});
next(action);
break;
@ -118225,11 +118225,12 @@ var CoreMiddleware = function () {
}
};
ensureItemLoaded({
ensureLoaded({
store: store,
action: action,
fetch: _fetch3,
dependents: ['tracks', 'albums_uris']
dependents: ['images'],
fullDependents: ['tracks', 'albums_uris']
});
next(action);
break;
@ -118254,11 +118255,12 @@ var CoreMiddleware = function () {
}
};
ensureItemLoaded({
ensureLoaded({
store: store,
action: action,
fetch: _fetch4,
dependents: ['tracks']
dependents: ['images'],
fullDependents: ['tracks']
});
next(action);
break;
@ -118283,11 +118285,11 @@ var CoreMiddleware = function () {
}
};
ensureItemLoaded({
ensureLoaded({
store: store,
dependents: ['playlists_uris'],
action: action,
fetch: _fetch5
fetch: _fetch5,
fullDependents: ['playlists_uris']
});
next(action);
break;
@ -118306,11 +118308,11 @@ var CoreMiddleware = function () {
}
};
ensureItemLoaded({
ensureLoaded({
store: store,
dependents: ['playlists_uris'],
action: action,
fetch: fetch
fetch: fetch,
fullDependents: ['playlists_uris']
});
next(action);
break;
@ -126691,6 +126693,8 @@ function getPlaylist(uri, _ref5) {
dispatch(coreActions.itemLoaded(_objectSpread(_objectSpread({}, Object(_util_format__WEBPACK_IMPORTED_MODULE_3__["formatPlaylist"])(response)), {}, {
can_edit: getState().spotify.me && getState().spotify.me.id === response.owner.id,
description: description
}, full ? {} : {
tracks: null
})));
if (full) {
@ -130596,7 +130600,7 @@ var getCurrentPusherConnection = function getCurrentPusherConnection(connections
var uriSource = function uriSource(uri) {
if (!uri) return false;
if (!uri) return '';
var exploded = "".concat(uri).split(':');
return exploded[0];
};
@ -130609,7 +130613,7 @@ var uriSource = function uriSource(uri) {
var uriType = function uriType(uri) {
if (!uri) return null;
if (!uri) return '';
var exploded = "".concat(uri).split(':');
if (exploded[0] === 'm3u') {
@ -130926,7 +130930,8 @@ var getIndexedRecords = function getIndexedRecords(index, uris) {
* */
var titleCase = function titleCase(string) {
var titleCase = function titleCase() {
var string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
return string.charAt(0).toUpperCase() + string.slice(1);
};
/**
@ -136558,7 +136563,9 @@ var Queue = /*#__PURE__*/function (_React$Component) {
added_from_uri = _this$props.added_from_uri;
if (added_from_uri && added_from_uri !== prev_added_from_uri) {
loadItem(added_from_uri);
loadItem(added_from_uri, {
full: false
});
}
});
@ -136892,13 +136899,9 @@ var Queue = /*#__PURE__*/function (_React$Component) {
_this$props6$location = _this$props6.location;
_this$props6$location = _this$props6$location === void 0 ? {} : _this$props6$location;
var limit = _this$props6$location.limit;
if (limit) {
this.setState({
limit: limit
});
}
if (limit) this.setState({
limit: limit
});
setWindowTitle(Object(_locale__WEBPACK_IMPORTED_MODULE_19__["i18n"])('now_playing.title'));
}
}, {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -106,7 +106,7 @@
// Release details
// These are automatically injected to built HTML
var build = "1601884219";
var build = "1601918816";
var version = "3.52.4";
// Construct the script tag

View File

@ -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');
}
}

View File

@ -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 {

View File

@ -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);

View File

@ -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) {

View File

@ -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);
};

View File

@ -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 });
}
}