Skip to content

Commit

Permalink
Play/Enqueue partially-loaded albums
Browse files Browse the repository at this point in the history
- 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?)
  • Loading branch information
jaedb committed Jun 25, 2023
1 parent fd91576 commit 39accaf
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 13 deletions.
8 changes: 5 additions & 3 deletions src/js/services/mopidy/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -957,17 +957,19 @@ const MopidyMiddleware = (function () {
store.dispatch(
coreActions.loadAlbum(
action.uri,
false,
{
name: 'enqueue',
...action,
callbackAction: {
name: 'enqueue',
...action,
},
},
),
);
break;
}

case 'MOPIDY_ENQUEUE_URIS': {
console.debug(action)
if (!action.uris || action.uris.length <= 0) {
this.props.uiActions.createNotification({
content: 'No URIs to enqueue',
Expand Down
25 changes: 24 additions & 1 deletion src/js/services/spotify/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()}`;
Expand All @@ -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({
Expand Down
49 changes: 40 additions & 9 deletions src/js/util/library.js
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -77,6 +82,7 @@ const ensureLoaded = ({
options: {
forceRefetch,
full,
callbackAction,
},
} = action;
const {
Expand All @@ -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;
}
Expand All @@ -108,31 +115,55 @@ 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;
}
}

// 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
Expand All @@ -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)
),
);
Expand Down

0 comments on commit 39accaf

Please sign in to comment.