In-memory search results cache
- Switching between type and provider now negates need for repeat queries - Mopidy caching varies, so for some providers this has a huge performance gain (eg YouTube) - Spotify will requery anyway, but the browser handles query caching
This commit is contained in:
@ -197,12 +197,12 @@ const CoreMiddleware = (function () {
|
|||||||
// Trigger reducer immediately; this will hose out any previous results
|
// Trigger reducer immediately; this will hose out any previous results
|
||||||
next(action);
|
next(action);
|
||||||
|
|
||||||
if (providers.includes('spotify:')) {
|
if (providers.includes('spotify')) {
|
||||||
store.dispatch(spotifyActions.getSearchResults(query));
|
store.dispatch(spotifyActions.getSearchResults(query));
|
||||||
}
|
}
|
||||||
store.dispatch(mopidyActions.getSearchResults(
|
store.dispatch(mopidyActions.getSearchResults(
|
||||||
query,
|
query,
|
||||||
providers.filter((i) => i !== 'spotify:'), // Omit Spotify; handled above
|
providers.filter((i) => i !== 'spotify'), // Omit Spotify; handled above
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import {
|
|||||||
indexToArray,
|
indexToArray,
|
||||||
} from '../../util/arrays';
|
} from '../../util/arrays';
|
||||||
import { getProvider, getSortSelector } from '../../util/selectors';
|
import { getProvider, getSortSelector } from '../../util/selectors';
|
||||||
|
import { iterate } from 'localforage';
|
||||||
|
|
||||||
const mopidyActions = require('./actions.js');
|
const mopidyActions = require('./actions.js');
|
||||||
const coreActions = require('../core/actions.js');
|
const coreActions = require('../core/actions.js');
|
||||||
@ -268,22 +269,28 @@ const MopidyMiddleware = (function () {
|
|||||||
method = 'library.search',
|
method = 'library.search',
|
||||||
data,
|
data,
|
||||||
} = queue.shift();
|
} = queue.shift();
|
||||||
const resultKey = getSearchResultKey({ provider, type, term });
|
|
||||||
const processKey = 'MOPIDY_GET_SEARCH_RESULTS';
|
const processKey = 'MOPIDY_GET_SEARCH_RESULTS';
|
||||||
const processor = store.getState().ui.processes[processKey];
|
const processor = store.getState().ui.processes[processKey];
|
||||||
|
|
||||||
if (processor && processor.status === 'cancelling') {
|
if (processor && processor.status === 'cancelling') {
|
||||||
store.dispatch(uiActions.processCancelled('MOPIDY_GET_SEARCH_RESULTS'));
|
store.dispatch(uiActions.processCancelled('MOPIDY_GET_SEARCH_RESULTS'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const iterateNext = (store, queue) => {
|
||||||
|
if (queue.length) {
|
||||||
|
processSearchQueue(store, queue);
|
||||||
|
} else {
|
||||||
|
store.dispatch(uiActions.processFinished(processKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
store.dispatch(uiActions.updateProcess(
|
store.dispatch(uiActions.updateProcess(
|
||||||
processKey,
|
processKey,
|
||||||
{
|
{
|
||||||
content: i18n(
|
content: i18n(
|
||||||
'services.mopidy.searching',
|
'services.mopidy.searching',
|
||||||
{
|
{
|
||||||
provider: titleCase(provider.replace(':', '')),
|
provider: titleCase(provider),
|
||||||
type: requestType,
|
type: requestType,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -291,6 +298,12 @@ const MopidyMiddleware = (function () {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
|
const resultKey = getSearchResultKey({ provider, type, term });
|
||||||
|
if (resultKey in store.getState().core.search_results) {
|
||||||
|
iterateNext(store, queue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Each type has a different method of formatting and destructuring.
|
// Each type has a different method of formatting and destructuring.
|
||||||
const processResults = {
|
const processResults = {
|
||||||
albums: (response) => {
|
albums: (response) => {
|
||||||
@ -377,12 +390,7 @@ const MopidyMiddleware = (function () {
|
|||||||
processResults[requestType](response),
|
processResults[requestType](response),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
iterateNext(store, queue);
|
||||||
if (queue.length) {
|
|
||||||
processSearchQueue(store, queue);
|
|
||||||
} else {
|
|
||||||
store.dispatch(uiActions.processFinished(processKey));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -1239,7 +1247,7 @@ const MopidyMiddleware = (function () {
|
|||||||
provider,
|
provider,
|
||||||
requestType: type,
|
requestType: type,
|
||||||
data: {
|
data: {
|
||||||
uris: [provider],
|
uris: [`${provider}:`],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|||||||
@ -603,8 +603,7 @@ const upgradeSpotifyPlaylistUri = function (uri) {
|
|||||||
return upgradeSpotifyPlaylistUris([uri])[0];
|
return upgradeSpotifyPlaylistUris([uri])[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSearchResultKey = ({ provider, type, term }) =>
|
const getSearchResultKey = ({ provider, type, term }) => [provider, type, term].join(':');
|
||||||
[provider.replace(':', ''), type, term].join(':');
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
debounce,
|
debounce,
|
||||||
|
|||||||
@ -7,11 +7,13 @@ const useSearchQuery = () => {
|
|||||||
type = 'all',
|
type = 'all',
|
||||||
providers: rawProviders = 'all',
|
providers: rawProviders = 'all',
|
||||||
} = useParams();
|
} = useParams();
|
||||||
const allProviders = useSelector((state) => state.mopidy?.uri_schemes || []);
|
const allProviders = useSelector(
|
||||||
|
({ mopidy: { uri_schemes } }) => uri_schemes || []
|
||||||
|
).map((str) => str.replace(/:/g,''));
|
||||||
const providers = rawProviders == 'all'
|
const providers = rawProviders == 'all'
|
||||||
? [...allProviders]
|
? [...allProviders]
|
||||||
: rawProviders.split(',').filter((str) => allProviders.indexOf(str) > -1);
|
: rawProviders.split(',').filter((str) => allProviders.indexOf(str) > -1);
|
||||||
const providersString = providers.join(',').replace(/:/g,'');
|
const providersString = providers.join(',');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
term,
|
term,
|
||||||
|
|||||||
@ -34,16 +34,15 @@ const Search = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(setWindowTitle('Search'));
|
dispatch(setWindowTitle('Search'));
|
||||||
$(document).find('.search-form input').focus();
|
$(document).find('.search-form input').trigger('focus');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (term) {
|
if (term) {
|
||||||
console.debug('STARTING SEARCH', { term, type, providers })
|
|
||||||
dispatch(setWindowTitle(i18n('search.title_window', { term: decodeURIComponent(term) })));
|
dispatch(setWindowTitle(i18n('search.title_window', { term: decodeURIComponent(term) })));
|
||||||
dispatch(startSearch({ term, type, providers }));
|
dispatch(startSearch({ term, type, providers }));
|
||||||
}
|
}
|
||||||
}, [])
|
}, [providersString, type, term])
|
||||||
|
|
||||||
const onSubmit = (term) => {
|
const onSubmit = (term) => {
|
||||||
updateSearchQuery(term, providers);
|
updateSearchQuery(term, providers);
|
||||||
@ -57,8 +56,6 @@ const Search = () => {
|
|||||||
const onReset = () => navigate('/search');
|
const onReset = () => navigate('/search');
|
||||||
|
|
||||||
const onProvidersChange = (providers) => {
|
const onProvidersChange = (providers) => {
|
||||||
console.debug(providers)
|
|
||||||
// ON BLUR then trigger search event
|
|
||||||
updateSearchQuery(term, providers)
|
updateSearchQuery(term, providers)
|
||||||
dispatch(hideContextMenu());
|
dispatch(hideContextMenu());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user