Upgrading other playlist views to use playlist providers selector
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
18
mopidy_iris/static/app.min.js
vendored
18
mopidy_iris/static/app.min.js
vendored
File diff suppressed because one or more lines are too long
@ -115,7 +115,7 @@
|
||||
|
||||
// Release details
|
||||
// These are automatically injected to built HTML
|
||||
var build = "1619945300";
|
||||
var build = "1620206341";
|
||||
var version = "3.57.6";
|
||||
|
||||
// Construct the script tag
|
||||
|
||||
@ -15,7 +15,6 @@ import {
|
||||
import {
|
||||
arrayOf,
|
||||
sortItems,
|
||||
indexToArray,
|
||||
} from '../util/arrays';
|
||||
import Link from './Link';
|
||||
import Icon from './Icon';
|
||||
@ -28,8 +27,18 @@ import * as pusherActions from '../services/pusher/actions';
|
||||
import * as mopidyActions from '../services/mopidy/actions';
|
||||
import * as lastfmActions from '../services/lastfm/actions';
|
||||
import * as spotifyActions from '../services/spotify/actions';
|
||||
import { I18n, i18n } from '../locale';
|
||||
import { collate, encodeUri } from '../util/format';
|
||||
import { I18n } from '../locale';
|
||||
import { encodeUri } from '../util/format';
|
||||
import {
|
||||
makeProcessProgressSelector,
|
||||
makeProvidersSelector,
|
||||
makeLibrarySelector,
|
||||
} from '../util/selectors';
|
||||
|
||||
const processKeys = [
|
||||
'MOPIDY_GET_LIBRARY_PLAYLISTS',
|
||||
'SPOTIFY_GET_LIBRARY_PLAYLISTS',
|
||||
];
|
||||
|
||||
class ContextMenu extends React.Component {
|
||||
constructor(props) {
|
||||
@ -750,28 +759,21 @@ class ContextMenu extends React.Component {
|
||||
|
||||
setSubmenu = (name) => {
|
||||
const { submenu } = this.state;
|
||||
if (submenu !== name && name === 'add-to-playlist') {
|
||||
this.getLibraries();
|
||||
}
|
||||
|
||||
this.setState({ submenu: name });
|
||||
}
|
||||
|
||||
getLibraries = () => {
|
||||
const {
|
||||
spotify_available,
|
||||
spotify_library_playlists: {
|
||||
items_uris: spotify_library,
|
||||
},
|
||||
mopidy_library_playlists: {
|
||||
items_uris: mopidy_library,
|
||||
},
|
||||
providers,
|
||||
coreActions: {
|
||||
loadLibrary,
|
||||
},
|
||||
} = this.props;
|
||||
if (submenu !== name && name === 'add-to-playlist') {
|
||||
if (spotify_available && !spotify_library.length) {
|
||||
loadLibrary('spotify:library:playlists', 'playlists');
|
||||
}
|
||||
if (!mopidy_library.length) {
|
||||
loadLibrary('mopidy:library:playlists', 'playlists');
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({ submenu: name });
|
||||
providers.forEach((provider) => loadLibrary(provider.uri, 'playlists'));
|
||||
}
|
||||
|
||||
closeSubmenu = () => this.setState({ submenu: null });
|
||||
@ -779,20 +781,13 @@ class ContextMenu extends React.Component {
|
||||
renderSubmenu = () => {
|
||||
const { submenu } = this.state;
|
||||
const {
|
||||
items,
|
||||
spotify_library_playlists,
|
||||
mopidy_library_playlists,
|
||||
playlists: allPlaylists,
|
||||
loading_progress,
|
||||
} = this.props;
|
||||
|
||||
let list = null;
|
||||
const isLoading = false;
|
||||
|
||||
if (submenu === 'add-to-playlist') {
|
||||
let playlists = [
|
||||
...(collate(spotify_library_playlists, { items }).items || []),
|
||||
...(collate(mopidy_library_playlists, { items }).items || []),
|
||||
];
|
||||
playlists = compact(playlists.map((playlist) => {
|
||||
let playlists = compact(allPlaylists.map((playlist) => {
|
||||
if (!playlist.can_edit) return null;
|
||||
return {
|
||||
...playlist,
|
||||
@ -847,7 +842,7 @@ class ContextMenu extends React.Component {
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
{isLoading ? (
|
||||
{loading_progress ? (
|
||||
<div className="context-menu__item context-menu__item--loader">
|
||||
<Loader className="context-menu__item" mini loading />
|
||||
</div>
|
||||
@ -1345,13 +1340,23 @@ class ContextMenu extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const librarySelector = makeLibrarySelector('playlists');
|
||||
const providersSelector = makeProvidersSelector('playlists');
|
||||
const processProgressSelector = makeProcessProgressSelector(processKeys);
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
providers: providersSelector(state),
|
||||
playlists: librarySelector(state, 'playlists'),
|
||||
loading_progress: processProgressSelector(state),
|
||||
menu: state.ui.context_menu,
|
||||
load_queue: state.ui.load_queue,
|
||||
processes: state.ui.processes,
|
||||
current_track: state.core.current_track,
|
||||
current_tracklist: state.core.current_tracklist,
|
||||
queue_metadata: state.core.queue_metadata,
|
||||
pinned: state.pusher.pinned,
|
||||
lastfm_authorized: state.lastfm.authorization,
|
||||
// TODO: Delete all of the below
|
||||
spotify_available: state.spotify.access_token,
|
||||
spotify_library_playlists: state.core.libraries['spotify:library:playlists'] || { items_uris: [] },
|
||||
spotify_library_artists: state.core.libraries['spotify:library:artists'] || { items_uris: [] },
|
||||
@ -1361,8 +1366,6 @@ const mapStateToProps = (state) => ({
|
||||
mopidy_library_artists: state.core.libraries['mopidy:library:artists'] || { items_uris: [] },
|
||||
mopidy_library_albums: state.core.libraries['mopidy:library:albums'] || { items_uris: [] },
|
||||
items: state.core.items,
|
||||
pinned: state.pusher.pinned,
|
||||
lastfm_authorized: state.lastfm.authorization,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
@ -149,6 +149,8 @@ services:
|
||||
unlove: Unlove
|
||||
youtube:
|
||||
title: YouTube
|
||||
tidal:
|
||||
title: Tidal
|
||||
|
||||
##
|
||||
# Components
|
||||
|
||||
@ -437,8 +437,11 @@ export function deletePlaylist(uri) {
|
||||
};
|
||||
}
|
||||
|
||||
export function getLibraryPlaylists() {
|
||||
return { type: 'MOPIDY_GET_LIBRARY_PLAYLISTS' };
|
||||
export function getLibraryPlaylists(uri) {
|
||||
return {
|
||||
type: 'MOPIDY_GET_LIBRARY_PLAYLISTS',
|
||||
uri,
|
||||
};
|
||||
}
|
||||
|
||||
export function getPlaylist(uri, options) {
|
||||
|
||||
@ -1668,9 +1668,19 @@ const MopidyMiddleware = (function () {
|
||||
subdirectories.push(formatArtist({ ...item, loading: true }));
|
||||
subdirectoryImagesToLoad.push(item.uri);
|
||||
} else if (item.__model__ === 'Ref' && item.type === 'playlist') {
|
||||
console.debug('playlist', { item })
|
||||
subdirectories.push(formatPlaylist({ ...item, loading: true }));
|
||||
subdirectoryImagesToLoad.push(item.uri);
|
||||
// Tidal moods and genres incorrectly marked as Playlist type
|
||||
if (
|
||||
item.uri.indexOf('tidal:mood') > -1 ||
|
||||
item.uri.indexOf('tidal:genre') > -1
|
||||
) {
|
||||
subdirectories.push({
|
||||
...item,
|
||||
type: 'directory',
|
||||
});
|
||||
} else {
|
||||
subdirectories.push(formatPlaylist({ ...item, loading: true }));
|
||||
subdirectoryImagesToLoad.push(item.uri);
|
||||
}
|
||||
} else {
|
||||
subdirectories.push(item);
|
||||
}
|
||||
@ -1770,7 +1780,7 @@ const MopidyMiddleware = (function () {
|
||||
if (!raw_response.length) {
|
||||
store.dispatch(coreActions.libraryLoaded({
|
||||
uri: 'mopidy:library:artists',
|
||||
type: action.uriType,
|
||||
type: 'artists',
|
||||
items_uris: [],
|
||||
}));
|
||||
store.dispatch(uiActions.processFinished(action.type));
|
||||
@ -1796,70 +1806,134 @@ const MopidyMiddleware = (function () {
|
||||
case 'MOPIDY_GET_LIBRARY_PLAYLISTS': {
|
||||
store.dispatch(uiActions.startProcess(action.type, { notification: false }));
|
||||
|
||||
request(store, 'playlists.asList')
|
||||
.then((listResponse) => {
|
||||
// Remove any Spotify playlists. These will be handled by our Spotify API
|
||||
const playlist_uris = arrayOf('uri', listResponse).filter(
|
||||
(playlistUri) => uriSource(playlistUri) !== 'spotify',
|
||||
);
|
||||
const libraryPlaylists = [];
|
||||
// Built-in playlist support works differently to other providers
|
||||
if (action.uri === 'm3u:playlists') {
|
||||
request(store, 'playlists.asList')
|
||||
.then((listResponse) => {
|
||||
const libraryPlaylists = [];
|
||||
const playlist_uris = arrayOf('uri', listResponse).filter(
|
||||
(pUri) => (pUri.indexOf('m3u') > -1),
|
||||
);
|
||||
store.dispatch(
|
||||
uiActions.updateProcess(
|
||||
action.type,
|
||||
{
|
||||
total: playlist_uris.length,
|
||||
remaining: playlist_uris.length,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
store.dispatch(
|
||||
uiActions.updateProcess(
|
||||
action.type,
|
||||
{
|
||||
total: playlist_uris.length,
|
||||
remaining: playlist_uris.length,
|
||||
},
|
||||
),
|
||||
);
|
||||
if (playlist_uris.length) {
|
||||
playlist_uris.forEach((uri, index) => {
|
||||
request(store, 'playlists.lookup', { uri })
|
||||
.then((response) => {
|
||||
if (response) {
|
||||
libraryPlaylists.push(
|
||||
formatPlaylist({
|
||||
name: response.name,
|
||||
uri: response.uri,
|
||||
can_edit: uriSource(response.uri) === 'm3u',
|
||||
last_modified: response.last_modified,
|
||||
// By not including actual tracks they will be fetched when needed. We don't
|
||||
// want these simple tracks because they don't contain duration, artist, etc.
|
||||
tracks_total: response.tracks ? response.tracks.length : null,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (playlist_uris.length) {
|
||||
playlist_uris.forEach((uri, index) => {
|
||||
request(store, 'playlists.lookup', { uri })
|
||||
.then((response) => {
|
||||
libraryPlaylists.push(
|
||||
formatPlaylist({
|
||||
name: response.name,
|
||||
uri: response.uri,
|
||||
can_edit: uriSource(response.uri) === 'm3u',
|
||||
last_modified: response.last_modified,
|
||||
// By not including actual tracks they will be fetched when needed. We don't
|
||||
// want these simple tracks because they don't contain duration, artist, etc.
|
||||
tracks_total: response.tracks ? response.tracks.length : null,
|
||||
}),
|
||||
);
|
||||
store.dispatch(
|
||||
uiActions.updateProcess(
|
||||
action.type,
|
||||
{
|
||||
remaining: playlist_uris.length - index - 1,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
store.dispatch(
|
||||
uiActions.updateProcess(
|
||||
action.type,
|
||||
{
|
||||
remaining: playlist_uris.length - index - 1,
|
||||
},
|
||||
),
|
||||
);
|
||||
if (index === playlist_uris.length - 1) {
|
||||
store.dispatch(coreActions.itemsLoaded(libraryPlaylists));
|
||||
store.dispatch(coreActions.libraryLoaded({
|
||||
uri: action.uri,
|
||||
type: 'playlists',
|
||||
items_uris: arrayOf('uri', libraryPlaylists),
|
||||
}));
|
||||
store.dispatch(uiActions.processFinished(action.type));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
store.dispatch(coreActions.libraryLoaded({
|
||||
uri: action.uri,
|
||||
type: 'playlists',
|
||||
items_uris: [],
|
||||
}));
|
||||
store.dispatch(uiActions.stopLoading('mopidy:library:playlists'));
|
||||
store.dispatch(uiActions.processFinished(action.type));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
request(store, 'library.browse', { uri: action.uri })
|
||||
.then((browseResponse) => {
|
||||
const libraryPlaylists = [];
|
||||
|
||||
if (index === playlist_uris.length - 1) {
|
||||
store.dispatch(coreActions.itemsLoaded(libraryPlaylists));
|
||||
store.dispatch(coreActions.libraryLoaded({
|
||||
uri: 'mopidy:library:playlists',
|
||||
type: action.uriType,
|
||||
items_uris: arrayOf('uri', libraryPlaylists),
|
||||
}));
|
||||
store.dispatch(uiActions.processFinished(action.type));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
store.dispatch(coreActions.libraryLoaded({
|
||||
uri: action.uri,
|
||||
type: 'playlists',
|
||||
items_uris: [],
|
||||
}));
|
||||
store.dispatch(uiActions.stopLoading('mopidy:library:playlists'));
|
||||
store.dispatch(uiActions.processFinished(action.type));
|
||||
}
|
||||
});
|
||||
store.dispatch(
|
||||
uiActions.updateProcess(
|
||||
action.type,
|
||||
{
|
||||
total: browseResponse.length,
|
||||
remaining: browseResponse.length,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (browseResponse.length) {
|
||||
browseResponse.forEach((playlist, index) => {
|
||||
request(store, 'library.lookup', { uris: [playlist.uri] })
|
||||
.then((response) => {
|
||||
if (response) {
|
||||
libraryPlaylists.push(
|
||||
formatPlaylist({
|
||||
name: playlist.name,
|
||||
uri: playlist.uri,
|
||||
can_edit: uriSource(playlist.uri) === 'm3u',
|
||||
last_modified: playlist.last_modified,
|
||||
tracks: formatTracks(response[playlist.uri]),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
store.dispatch(
|
||||
uiActions.updateProcess(
|
||||
action.type,
|
||||
{
|
||||
remaining: browseResponse.length - index - 1,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (index === browseResponse.length - 1) {
|
||||
store.dispatch(coreActions.itemsLoaded(libraryPlaylists));
|
||||
store.dispatch(coreActions.libraryLoaded({
|
||||
uri: action.uri,
|
||||
type: 'playlists',
|
||||
items_uris: arrayOf('uri', libraryPlaylists),
|
||||
}));
|
||||
store.dispatch(uiActions.processFinished(action.type));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
store.dispatch(coreActions.libraryLoaded({
|
||||
uri: action.uri,
|
||||
type: 'playlists',
|
||||
items_uris: [],
|
||||
}));
|
||||
store.dispatch(uiActions.stopLoading('mopidy:library:playlists'));
|
||||
store.dispatch(uiActions.processFinished(action.type));
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1868,7 +1942,6 @@ const MopidyMiddleware = (function () {
|
||||
|
||||
request(store, 'library.browse', { uri: action.uri })
|
||||
.then((browseResponse) => {
|
||||
console.debug({ action, browseResponse })
|
||||
const allUris = arrayOf('uri', browseResponse);
|
||||
|
||||
store.dispatch(uiActions.updateProcess(
|
||||
|
||||
@ -99,6 +99,23 @@ const makeProcessProgressSelector = (keys) => createSelector(
|
||||
);
|
||||
|
||||
const providers = {
|
||||
playlists: [
|
||||
{
|
||||
scheme: 'm3u:',
|
||||
uri: 'm3u:playlists',
|
||||
title: i18n('services.mopidy.local'),
|
||||
},
|
||||
{
|
||||
scheme: 'spotify:',
|
||||
uri: 'spotify:library:playlists',
|
||||
title: i18n('services.spotify.title'),
|
||||
},
|
||||
{
|
||||
scheme: 'tidal:',
|
||||
uri: 'tidal:my_playlists',
|
||||
title: i18n('services.tidal.title'),
|
||||
},
|
||||
],
|
||||
albums: [
|
||||
{
|
||||
scheme: 'local:',
|
||||
@ -115,6 +132,11 @@ const providers = {
|
||||
uri: 'spotify:library:albums',
|
||||
title: i18n('services.spotify.title'),
|
||||
},
|
||||
{
|
||||
scheme: 'tidal:',
|
||||
uri: 'tidal:my_albums',
|
||||
title: i18n('services.tidal.title'),
|
||||
},
|
||||
{
|
||||
scheme: 'ytmusic:',
|
||||
uri: 'ytmusic:album',
|
||||
@ -137,6 +159,11 @@ const providers = {
|
||||
uri: 'spotify:library:artists',
|
||||
title: i18n('services.spotify.title'),
|
||||
},
|
||||
{
|
||||
scheme: 'tidal:',
|
||||
uri: 'tidal:my_artists',
|
||||
title: i18n('services.tidal.title'),
|
||||
},
|
||||
{
|
||||
scheme: 'ytmusic:',
|
||||
uri: 'ytmusic:artist',
|
||||
|
||||
@ -18,6 +18,7 @@ import Loader from '../../components/Loader';
|
||||
import {
|
||||
makeLibrarySelector,
|
||||
makeProcessProgressSelector,
|
||||
makeProvidersSelector,
|
||||
getLibrarySource,
|
||||
} from '../../util/selectors';
|
||||
|
||||
@ -44,16 +45,14 @@ class LibraryPlaylists extends React.Component {
|
||||
|
||||
setWindowTitle(i18n('library.playlists.title'));
|
||||
|
||||
this.getMopidyLibrary();
|
||||
this.getSpotifyLibrary();
|
||||
this.getLibraries();
|
||||
}
|
||||
|
||||
refresh = () => {
|
||||
const { uiActions: { hideContextMenu } } = this.props;
|
||||
|
||||
hideContextMenu();
|
||||
this.getMopidyLibrary(true);
|
||||
this.getSpotifyLibrary(true);
|
||||
this.getLibraries(true);
|
||||
}
|
||||
|
||||
cancelRefresh = () => {
|
||||
@ -63,46 +62,35 @@ class LibraryPlaylists extends React.Component {
|
||||
cancelProcess(processKeys);
|
||||
}
|
||||
|
||||
getMopidyLibrary = (forceRefetch = false) => {
|
||||
const {
|
||||
source,
|
||||
coreActions: {
|
||||
loadLibrary,
|
||||
},
|
||||
} = this.props;
|
||||
|
||||
if (source !== 'local' && source !== 'all') return;
|
||||
|
||||
loadLibrary('mopidy:library:playlists', 'playlists', { forceRefetch });
|
||||
};
|
||||
|
||||
getSpotifyLibrary = (forceRefetch = false) => {
|
||||
const {
|
||||
source,
|
||||
spotify_available,
|
||||
coreActions: {
|
||||
loadLibrary,
|
||||
},
|
||||
} = this.props;
|
||||
|
||||
if (!spotify_available) return;
|
||||
if (source !== 'spotify' && source !== 'all') return;
|
||||
|
||||
loadLibrary('spotify:library:playlists', 'playlists', { forceRefetch });
|
||||
};
|
||||
|
||||
componentDidUpdate = ({ source: prevSource }) => {
|
||||
const { source } = this.props;
|
||||
|
||||
if (source !== prevSource) {
|
||||
this.getMopidyLibrary();
|
||||
this.getSpotifyLibrary();
|
||||
this.getLibraries();
|
||||
}
|
||||
}
|
||||
|
||||
getLibraries = (forceRefetch = false) => {
|
||||
const {
|
||||
source,
|
||||
providers,
|
||||
coreActions: {
|
||||
loadLibrary,
|
||||
},
|
||||
} = this.props;
|
||||
|
||||
let uris = [];
|
||||
if (source === 'all') {
|
||||
uris = providers.map((p) => p.uri);
|
||||
} else {
|
||||
uris.push(source);
|
||||
}
|
||||
uris.forEach((uri) => loadLibrary(uri, 'playlists', { forceRefetch }));
|
||||
};
|
||||
|
||||
setSort(value) {
|
||||
let reverse = false;
|
||||
if (this.props.sort == value) reverse = !this.props.sort_reverse;
|
||||
if (this.props.sort === value) reverse = !this.props.sort_reverse;
|
||||
|
||||
const data = {
|
||||
library_playlists_sort_reverse: reverse,
|
||||
@ -169,7 +157,7 @@ class LibraryPlaylists extends React.Component {
|
||||
render = () => {
|
||||
const {
|
||||
uiActions,
|
||||
spotify_available,
|
||||
providers,
|
||||
source,
|
||||
sort,
|
||||
sort_reverse,
|
||||
@ -180,24 +168,6 @@ class LibraryPlaylists extends React.Component {
|
||||
filter,
|
||||
} = this.state;
|
||||
|
||||
const source_options = [
|
||||
{
|
||||
value: 'all',
|
||||
label: i18n('fields.filters.all'),
|
||||
},
|
||||
{
|
||||
value: 'local',
|
||||
label: i18n('services.mopidy.local'),
|
||||
},
|
||||
];
|
||||
|
||||
if (spotify_available) {
|
||||
source_options.push({
|
||||
value: 'spotify',
|
||||
label: i18n('services.spotify.title'),
|
||||
});
|
||||
}
|
||||
|
||||
const view_options = [
|
||||
{
|
||||
value: 'thumbnails',
|
||||
@ -269,7 +239,13 @@ class LibraryPlaylists extends React.Component {
|
||||
name={i18n('fields.source')}
|
||||
valueAsLabel
|
||||
value={source}
|
||||
options={source_options}
|
||||
options={[
|
||||
{
|
||||
value: 'all',
|
||||
label: i18n('fields.filters.all'),
|
||||
},
|
||||
...providers.map((p) => ({ value: p.uri, label: p.title })),
|
||||
]}
|
||||
handleChange={(value) => { uiActions.set({ library_playlists_source: value }); uiActions.hideContextMenu(); }}
|
||||
/>
|
||||
<Button
|
||||
@ -307,6 +283,7 @@ class LibraryPlaylists extends React.Component {
|
||||
|
||||
const librarySelector = makeLibrarySelector('playlists');
|
||||
const processProgressSelector = makeProcessProgressSelector(processKeys);
|
||||
const providersSelector = makeProvidersSelector('playlists');
|
||||
const mapStateToProps = (state) => {
|
||||
const {
|
||||
spotify: {
|
||||
@ -318,8 +295,7 @@ const mapStateToProps = (state) => {
|
||||
|
||||
return {
|
||||
slim_mode: state.ui.slim_mode,
|
||||
mopidy_uri_schemes: state.mopidy.uri_schemes,
|
||||
spotify_available: state.spotify.access_token,
|
||||
providers: providersSelector(state),
|
||||
playlists: librarySelector(state, 'playlists'),
|
||||
loading_progress: processProgressSelector(state),
|
||||
source: getLibrarySource(state, 'playlists'),
|
||||
|
||||
@ -12,8 +12,12 @@ import * as spotifyActions from '../../services/spotify/actions';
|
||||
import { sourceIcon } from '../../util/helpers';
|
||||
import { sortItems } from '../../util/arrays';
|
||||
import { I18n, i18n } from '../../locale';
|
||||
import { collate, decodeUri } from '../../util/format';
|
||||
import { makeProcessProgressSelector } from '../../util/selectors';
|
||||
import { decodeUri } from '../../util/format';
|
||||
import {
|
||||
makeProcessProgressSelector,
|
||||
makeProvidersSelector,
|
||||
makeLibrarySelector,
|
||||
} from '../../util/selectors';
|
||||
|
||||
const processKeys = [
|
||||
'MOPIDY_GET_LIBRARY_PLAYLISTS',
|
||||
@ -23,32 +27,26 @@ const processKeys = [
|
||||
class AddToPlaylist extends React.Component {
|
||||
componentDidMount = () => {
|
||||
const {
|
||||
spotify_library: {
|
||||
items_uris: spotify_library,
|
||||
},
|
||||
mopidy_library: {
|
||||
items_uris: mopidy_library,
|
||||
},
|
||||
spotify_available,
|
||||
coreActions: {
|
||||
loadLibrary,
|
||||
},
|
||||
uiActions: {
|
||||
setWindowTitle,
|
||||
},
|
||||
} = this.props;
|
||||
|
||||
if (!spotify_library.length && spotify_available) {
|
||||
loadLibrary('spotify:library:playlists', 'playlists');
|
||||
}
|
||||
|
||||
if (!mopidy_library.length) {
|
||||
loadLibrary('mopidy:library:playlists', 'playlists');
|
||||
}
|
||||
|
||||
this.getLibraries();
|
||||
setWindowTitle(i18n('modal.add_to_playlist.title'));
|
||||
}
|
||||
|
||||
getLibraries = () => {
|
||||
const {
|
||||
providers,
|
||||
coreActions: {
|
||||
loadLibrary,
|
||||
},
|
||||
} = this.props;
|
||||
|
||||
providers.forEach((provider) => loadLibrary(provider.uri, 'playlists'));
|
||||
};
|
||||
|
||||
playlistSelected = (playlist_uri) => {
|
||||
const {
|
||||
coreActions: {
|
||||
@ -62,9 +60,7 @@ class AddToPlaylist extends React.Component {
|
||||
|
||||
renderList = () => {
|
||||
const {
|
||||
items,
|
||||
spotify_library = { items_uris: [] },
|
||||
mopidy_library = { items_uris: [] },
|
||||
playlists: allPlaylists,
|
||||
loading_progress,
|
||||
} = this.props;
|
||||
|
||||
@ -72,11 +68,7 @@ class AddToPlaylist extends React.Component {
|
||||
return <Loader body loading progress={loading_progress} />;
|
||||
}
|
||||
|
||||
let playlists = [
|
||||
...(collate(spotify_library, { items }).items),
|
||||
...(collate(mopidy_library, { items }).items),
|
||||
].filter((playlist) => playlist.can_edit);
|
||||
|
||||
let playlists = allPlaylists.filter((playlist) => playlist.can_edit);
|
||||
playlists = sortItems(playlists, 'name');
|
||||
|
||||
if (playlists.length > 0) {
|
||||
@ -128,6 +120,9 @@ class AddToPlaylist extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const librarySelector = makeLibrarySelector('playlists');
|
||||
const processProgressSelector = makeProcessProgressSelector(processKeys);
|
||||
const providersSelector = makeProvidersSelector('playlists');
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const {
|
||||
spotify: {
|
||||
@ -136,29 +131,18 @@ const mapStateToProps = (state, ownProps) => {
|
||||
} = {},
|
||||
access_token: spotify_available,
|
||||
},
|
||||
core: {
|
||||
playlists,
|
||||
items,
|
||||
libraries,
|
||||
},
|
||||
mopidy: {
|
||||
uri_schemes: mopidy_uri_schemes,
|
||||
},
|
||||
} = state;
|
||||
const processProgressSelector = makeProcessProgressSelector(processKeys);
|
||||
const unencodedUris = ownProps.match.params?.uris.split(',');
|
||||
const uris = unencodedUris ? unencodedUris.map((uri) => decodeUri(uri)) : [];
|
||||
|
||||
const unencodedUris = ownProps.match.params?.uris;
|
||||
const uris = unencodedUris ? decodeUri(unencodedUris).split(',') : [];
|
||||
|
||||
return {
|
||||
uris,
|
||||
mopidy_uri_schemes,
|
||||
items,
|
||||
mopidy_library: libraries['mopidy:library:playlists'] || { items_uris: [] },
|
||||
spotify_library: libraries['spotify:library:playlists'] || { items_uris: [] },
|
||||
providers: providersSelector(state),
|
||||
playlists: librarySelector(state, 'playlists'),
|
||||
spotify_available,
|
||||
loading_progress: processProgressSelector(state),
|
||||
me_id,
|
||||
playlists,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user