From 39accaf362d61a2064d3a371d478f0663ba71648 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Sun, 25 Jun 2023 18:12:39 +1200 Subject: [PATCH] Play/Enqueue partially-loaded albums - When in index, but tracks are not, our callbackAction is not triggered - Send and consume our `callbackAction` as per Playlists - Added support to our `ensureLoaded` handler; This will need some observation and testing to ensure there is no knock-on issues (possibly double-ups?) --- src/js/services/mopidy/middleware.js | 8 +++-- src/js/services/spotify/actions.js | 25 +++++++++++++- src/js/util/library.js | 49 +++++++++++++++++++++++----- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js index 54339d3e..310019df 100755 --- a/src/js/services/mopidy/middleware.js +++ b/src/js/services/mopidy/middleware.js @@ -957,10 +957,11 @@ const MopidyMiddleware = (function () { store.dispatch( coreActions.loadAlbum( action.uri, - false, { - name: 'enqueue', - ...action, + callbackAction: { + name: 'enqueue', + ...action, + }, }, ), ); @@ -968,6 +969,7 @@ const MopidyMiddleware = (function () { } case 'MOPIDY_ENQUEUE_URIS': { + console.debug(action) if (!action.uris || action.uris.length <= 0) { this.props.uiActions.createNotification({ content: 'No URIs to enqueue', diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index 66a73519..e34a8c71 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -1130,7 +1130,9 @@ export function getUser(uri, { full, forceRefetch } = {}) { * * @oaram uri string * */ -export function getAlbum(uri, { full, forceRefetch } = {}) { +export function getAlbum(uri, options = {}) { + const { full, forceRefetch, callbackAction } = options; + return (dispatch, getState) => { let endpoint = `albums/${getFromUri('albumid', uri)}`; if (forceRefetch) endpoint += `?refetch=${Date.now()}`; @@ -1146,6 +1148,27 @@ export function getAlbum(uri, { full, forceRefetch } = {}) { ...formatAlbum(response), })); + if (callbackAction) { + switch (callbackAction.name) { + case 'enqueue': + dispatch(mopidyActions.enqueueURIs({ + uris: [uri], + from: formatContext(response), + ...callbackAction, + })); + break; + case 'play': + dispatch(mopidyActions.playURIs({ + uris: [uri], + from: formatContext(response), + ...callbackAction, + })); + break; + default: + break; + } + } + if (full) { let tracks = formatTracks(response.tracks.items); const fetchTracks = (endpoint) => request({ diff --git a/src/js/util/library.js b/src/js/util/library.js index b80c92b1..4b45c578 100644 --- a/src/js/util/library.js +++ b/src/js/util/library.js @@ -1,8 +1,13 @@ import { compact } from 'lodash'; +import { formatContext } from './format'; import localForage from 'localforage'; - -const coreActions = require('../services/core/actions.js'); -const uiActions = require('../services/ui/actions.js'); +import { stopLoading } from '../services/ui/actions'; +import { enqueueURIs, playURIs } from '../services/mopidy/actions'; +import { + setLoading, + loadItems, + restoreItemsFromColdStore, +} from '../services/core/actions'; /** * Inspect object to check for missing dependent properties @@ -77,6 +82,7 @@ const ensureLoaded = ({ options: { forceRefetch, full, + callbackAction, }, } = action; const { @@ -86,11 +92,12 @@ const ensureLoaded = ({ } = {}, } = {}, } = store.getState(); + const dispatch = store.dispatch; // Forced refetch bypasses everything if (forceRefetch) { console.info(`Force-refetching "${uri}"`); - store.dispatch(coreActions.setLoading(uri, true)); + store.dispatch(setLoading(uri, true)); fetch(); return; } @@ -108,17 +115,40 @@ const ensureLoaded = ({ fullDependents, }); + const runCallback = (item) => { + switch (callbackAction.name) { + case 'enqueue': + dispatch(enqueueURIs({ + uris: [item.uri], + from: formatContext(item), + ...callbackAction, + })); + break; + case 'play': + dispatch(playURIs({ + uris: [item.uri], + from: formatContext(item), + ...callbackAction, + })); + break; + default: + break; + } + } + // Item already in our index? if (item) { if (missingDependents(item).length === 0) { - store.dispatch(uiActions.stopLoading(uri)); + store.dispatch(stopLoading(uri)); console.info(`"${uri}" already in index`); const uris = dependentUris(item); if (uris.length) { console.info(`Loading ${uris.length} dependents`, { uris }); - store.dispatch(coreActions.loadItems(type, uris)); + store.dispatch(loadItems(type, uris)); } + + if (callbackAction) runCallback(item); return; } } @@ -126,13 +156,14 @@ const ensureLoaded = ({ // What about in the coldstore? localForage.getItem(uri).then((restoredItem) => { if (!restoredItem || missingDependents(restoredItem).length > 0) { - store.dispatch(coreActions.setLoading(uri, true)); + store.dispatch(setLoading(uri, true)); fetch(); return; } console.info(`Restoring "${uri}" from database`); - store.dispatch(coreActions.restoreItemsFromColdStore([restoredItem])); + store.dispatch(restoreItemsFromColdStore([restoredItem])); + if (callbackAction) runCallback(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 @@ -147,7 +178,7 @@ const ensureLoaded = ({ Promise.all(restoreAllDependents).then( (dependentItems) => { store.dispatch( - coreActions.restoreItemsFromColdStore( + restoreItemsFromColdStore( compact(dependentItems), // Squash nulls (ie items not found in coldstore) ), );