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?)
This commit is contained in:
James Barnsley
2023-06-25 18:12:39 +12:00
parent fd91576103
commit 39accaf362
3 changed files with 69 additions and 13 deletions

View File

@ -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',

View File

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

View File

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