Refactor of isLoading for array of matches now staggered

This commit is contained in:
James Barnsley
2021-01-31 13:33:24 +13:00
parent 40e6ed5045
commit 1d77d497be
11 changed files with 142 additions and 147 deletions

View File

@ -390,18 +390,20 @@ const CoreMiddleware = (function () {
}
case 'LOAD_TRACK': {
const { uri, options } = action;
const fetch = () => {
switch (uriSource(action.uri)) {
case 'spotify':
store.dispatch(spotifyActions.getTrack(action.uri, action.options));
store.dispatch(spotifyActions.getTrack(uri, options));
if (spotify.me) {
store.dispatch(spotifyActions.following(action.uri));
store.dispatch(spotifyActions.following(uri));
}
break;
default:
store.dispatch(mopidyActions.getTrack(action.uri, action.options));
store.dispatch(mopidyActions.getTrack(uri, options));
break;
}
};
@ -410,7 +412,7 @@ const CoreMiddleware = (function () {
action,
fetch,
dependents: ['images'],
fullDependents: ['lyrics_results'],
fullDependents: options.lyrics ? ['lyrics_results'] : [],
type: 'track',
});

View File

@ -1530,8 +1530,8 @@ const MopidyMiddleware = (function () {
break;
case 'MOPIDY_GET_TRACKS': {
const { options: { full } } = action;
request(store, 'library.lookup', { uris: action.uris })
const { uris, options: { full, lyrics } } = action;
request(store, 'library.lookup', { uris })
.then(
(_response) => {
if (!_response) return;
@ -1542,16 +1542,16 @@ const MopidyMiddleware = (function () {
store.dispatch(coreActions.itemsLoaded(tracks));
store.dispatch(mopidyActions.getImages(arrayOf('uri', tracks)));
if (full) {
tracks.forEach((track) => {
tracks.forEach((track) => {
if (full) {
if (store.getState().lastfm.authorization) {
store.dispatch(lastfmActions.getTrack(track.uri));
}
if (store.getState().genius.authorization) {
store.dispatch(geniusActions.findTrackLyrics(track.uri));
}
});
}
}
if (lyrics && store.getState().genius.authorization) {
store.dispatch(geniusActions.findTrackLyrics(track.uri));
}
});
},
(error) => {
store.dispatch(coreActions.handleException(

View File

@ -56,6 +56,8 @@ const request = ({
const loaderKey = `spotify_${uri ? `uri_${uri}` : ''}_endpoint_${endpoint}`;
dispatch(uiActions.startLoading(loaderId, loaderKey));
console.debug({ loaderId, loaderKey })
return new Promise((resolve, reject) => {
getToken(dispatch, getState)
.then(
@ -332,7 +334,7 @@ export function getMe() {
};
}
export function getTrack(uri, { forceRefetch, full }) {
export function getTrack(uri, { forceRefetch, full, lyrics }) {
return (dispatch, getState) => {
let endpoint = `tracks/${getFromUri('trackid', uri)}`;
if (forceRefetch) endpoint += `?refetch=${Date.now()}`;
@ -350,9 +352,9 @@ export function getTrack(uri, { forceRefetch, full }) {
if (getState().lastfm.authorization) {
dispatch(lastfmActions.getTrack(uri));
}
if (getState().genius.authorization) {
dispatch(geniusActions.findTrackLyrics(uri));
}
}
if (lyrics && getState().genius.authorization) {
dispatch(geniusActions.findTrackLyrics(uri));
}
},
);

View File

@ -278,18 +278,10 @@ const formatSimpleObjects = function (records = []) {
/**
* Prepare a URI for use in a URL
*
* Needs to have all special characters encoded to avoid being parsed incorrectly, especially
* '/' as this is a URL parameter delimiter
* Simple alias to encodeURIComponent so this can be extended as needed
* @param {String} uri
*/
const encodeUri = (rawUri = '') => {
let uri = encodeURIComponent(rawUri);
// Double-encode percent symbol as Mopidy requires some encoded elements
//uri = uri.replace(/%/g, '%25');
return uri;
};
const encodeUri = (rawUri = '') => encodeURIComponent(rawUri);
/**
* Rebuild a URI with some ugly-ass handling of encoding.
@ -320,6 +312,7 @@ const decodeUri = (rawUri = '') => {
uri = uri.replace(/@/g, '%40');
uri = uri.replace(/#/g, '%23');
uri = uri.replace(/\$/g, '%24');
uri = uri.replace(/&/g, '%26');
uri = uri.replace(/'/g, '%27');
uri = uri.replace(/,/g, '%2C');
uri = uri.replace(/ /g, '%20');

View File

@ -1,4 +1,4 @@
import { indexToArray } from "./arrays";
import { indexToArray, arrayOf } from "./arrays";
import { encodeUri } from "./format";
/**
@ -370,37 +370,42 @@ let isObject = function (value) {
return value instanceof Object && value.constructor === Object;
};
/**
* Convert an array of strings to an array of RegExp objects
*
* @param {Array} keys
*/
const toRegExp = function (keys) {
return keys.map((key) => {
try {
return new RegExp(key);
} catch {
// Fucks with unit tests, but helpful for debugging.
// console.error('Could not convert string to RegEx', key);
return null;
}
});
};
/**
* Detect if an item is in the loading queue. We simply loop all load items to
* see if any items contain our searched key.
* see if any load queue keys match our 'includes' expression AND our 'excludes' expression(s)
*
* TODO: Explore performance of this
* TODO: Allow wildcards
*
* @param load_queue = obj (passed from store)
* @param key = string (the string to lookup)
* @return boolean
* @param {Object} load_queue (passed from store)
* @param {Array} keys array of regex strings
* @return {Boolean}
* */
const isLoading = function (load_queue = {}, keys = []) {
if (!load_queue || !keys) return false;
const expressions = toRegExp(keys);
const queue = indexToArray(load_queue);
const matches = keys.reduce((acc, key) => {
let regex = '';
try {
regex = new RegExp(key);
} catch {
// Fucks with unit tests, but helpful for debugging.
// console.error('Invalid regular expression', keys);
return acc;
}
return [
...acc,
...(queue.filter((qk) => qk.match(regex))),
];
}, []);
const matches = queue.filter((qk) => {
const matchingExpressions = keys.filter((exp) => qk.match(exp));
return (matchingExpressions.length === expressions.length);
});
return matches.length > 0;
};

View File

@ -115,7 +115,7 @@ const ensureLoaded = ({
const uris = dependentUris(item);
if (uris.length) {
console.log(`Loading ${uris.length} dependents`);
console.info(`Loading ${uris.length} dependents`);
store.dispatch(coreActions.loadItems(type, uris));
}
return;
@ -124,10 +124,7 @@ const ensureLoaded = ({
// What about in the coldstore?
localForage.getItem(uri).then((restoredItem) => {
if (
!restoredItem ||
missingDependents(restoredItem).length > 0
) {
if (!restoredItem || missingDependents(restoredItem).length > 0) {
fetch();
return;
}

View File

@ -366,7 +366,7 @@ class Album extends React.Component {
const mapStateToProps = (state, ownProps) => {
const uri = decodeURIComponent(ownProps.match.params.uri);
const itemSelector = makeItemSelector(uri);
const loadingSelector = makeLoadingSelector([`^(.*)${uri}(.*)(?!contains)(.*)$`]);
const loadingSelector = makeLoadingSelector([`(.*)${uri}(.*)`, '^((?!contains).)*$', '^((?!me/albums).)*$']);
return {
uri,
slim_mode: state.ui.slim_mode,

View File

@ -604,7 +604,7 @@ class Artist extends React.Component {
const mapStateToProps = (state, ownProps) => {
const uri = decodeURIComponent(ownProps.match.params.uri);
const loadingSelector = makeLoadingSelector([`(.*)${uri}(.*)`]);
const loadingSelector = makeLoadingSelector([`(.*)${uri}(.*)`, '^((?!contains).)*$', '^((?!/albums).)*$', '^((?!related-artists).)*$', '^((?!top-tracks).)*$']);
const artistSelector = makeItemSelector(uri);
const artist = artistSelector(state);
let albums = null;

View File

@ -143,7 +143,7 @@ class Track extends React.Component {
},
} = this.props;
loadTrack(decodeUri(uri));
loadTrack(decodeUri(uri), { full: true, lyrics: true });
if (track) {
this.setWindowTitle(track);
@ -157,28 +157,13 @@ class Track extends React.Component {
const {
uri,
track,
genius_authorized,
lastfm_authorized,
coreActions: {
loadTrack,
},
geniusActions: {
findTrackLyrics,
},
lastfmActions: {
getTrack,
},
} = this.props;
if (prevUri !== uri) {
loadTrack(decodeUri(uri));
}
// We have just received our full track or our track artists
if ((!prevTrack && track) || (prevTrack && !prevTrack.artists && track.artists)) {
this.setWindowTitle(track);
if (lastfm_authorized) getTrack(track.uri);
if (genius_authorized && !track.lyrics_results) findTrackLyrics(track);
loadTrack(decodeUri(uri), { full: true, lyrics: true });
}
if (!prevTrack && track) this.setWindowTitle(track);
@ -339,10 +324,12 @@ class Track extends React.Component {
const mapStateToProps = (state, ownProps) => {
const uri = decodeUri(ownProps.match.params.uri);
const loadingSelector = makeLoadingSelector([`^(?!genius)(.*)${uri}(.*)$`]);
const loadingSelector = makeLoadingSelector([`(.*)${uri}(.*)`, '^((?!genius).)*$', '^((?!contains).)*$']);
const loadingLyricsSelector = makeLoadingSelector([`^genius_(.*)lyrics_${uri}$`]);
const trackSelector = makeItemSelector(uri);
console.debug(`^(?!genius)(.*)${uri}(.*)(?!contains)(.*)$`)
return {
uri,
slim_mode: state.ui.slim_mode,