diff --git a/ui/src/actions/dialogs.js b/ui/src/actions/dialogs.js index dea4d6203..d637f7bff 100644 --- a/ui/src/actions/dialogs.js +++ b/ui/src/actions/dialogs.js @@ -29,9 +29,10 @@ export const closeShareMenu = () => ({ type: SHARE_MENU_CLOSE, }) -export const openAddToPlaylist = ({ selectedIds, onSuccess }) => ({ +export const openAddToPlaylist = ({ selectedIds, albumIds, onSuccess }) => ({ type: ADD_TO_PLAYLIST_OPEN, selectedIds, + albumIds, onSuccess, }) diff --git a/ui/src/album/AlbumActions.jsx b/ui/src/album/AlbumActions.jsx index bd782b25c..b62fa12fc 100644 --- a/ui/src/album/AlbumActions.jsx +++ b/ui/src/album/AlbumActions.jsx @@ -21,7 +21,6 @@ import { playNext, addTracks, playTracks, - shuffleTracks, openAddToPlaylist, openDownloadMenu, DOWNLOAD_MENU_ALBUM, @@ -99,29 +98,30 @@ const AlbumActions = ({ }, [getAllSongsAndDispatch]) const handleShuffle = React.useCallback(() => { - getAllSongsAndDispatch(shuffleTracks) - }, [getAllSongsAndDispatch]) - - const handleAddToPlaylist = React.useCallback(() => { - if (ids && ids.length === record.songCount) { - const selectedIds = ids.filter((id) => !data[id].missing) - return dispatch(openAddToPlaylist({ selectedIds })) + const filter = { album_id: record.id } + if (config.skipLowRatingInShuffle) { + filter.not_disliked = true } dataProvider .getList('song', { - pagination: { page: 1, perPage: 0 }, - sort: { field: 'album', order: 'ASC' }, - filter: { album_id: record.id }, + pagination: { page: 1, perPage: 500 }, + sort: { field: 'random', order: 'ASC' }, + filter, }) .then((res) => { - const selectedIds = res.data - .filter((s) => !s.missing) - .map((s) => s.id) - dispatch(openAddToPlaylist({ selectedIds })) + const allData = res.data.reduce( + (acc, curr) => ({ ...acc, [curr.id]: curr }), + {}, + ) + dispatch(playTracks(allData)) }) .catch(() => { notify('ra.page.error', 'warning') }) + }, [dataProvider, dispatch, record, notify]) + + const handleAddToPlaylist = React.useCallback(() => { + dispatch(openAddToPlaylist({ albumIds: [record.id] })) }, [dataProvider, dispatch, record, data, ids, notify]) const handleShare = React.useCallback(() => { diff --git a/ui/src/dialogs/AddToPlaylistDialog.jsx b/ui/src/dialogs/AddToPlaylistDialog.jsx index 91521d1ce..c9c603107 100644 --- a/ui/src/dialogs/AddToPlaylistDialog.jsx +++ b/ui/src/dialogs/AddToPlaylistDialog.jsx @@ -39,7 +39,7 @@ const useStyles = makeStyles({ export const AddToPlaylistDialog = () => { const classes = useStyles() - const { open, selectedIds, onSuccess, duplicateSong, duplicateIds } = + const { open, selectedIds, albumIds, onSuccess, duplicateSong, duplicateIds } = useSelector((state) => state.addToPlaylistDialog) const dispatch = useDispatch() const translate = useTranslate() @@ -61,10 +61,11 @@ export const AddToPlaylistDialog = () => { const addToPlaylist = (playlistId, distinctIds) => { const trackIds = Array.isArray(distinctIds) ? distinctIds : selectedIds - if (trackIds.length) { + const data = albumIds?.length ? { albumIds } : { ids: trackIds } + if (albumIds?.length || trackIds.length) { dataProvider .create('playlistTrack', { - data: { ids: trackIds }, + data, filter: { playlist_id: playlistId }, }) .then(() => { diff --git a/ui/src/reducers/dialogReducer.js b/ui/src/reducers/dialogReducer.js index e1a77f100..a9924dfca 100644 --- a/ui/src/reducers/dialogReducer.js +++ b/ui/src/reducers/dialogReducer.js @@ -63,6 +63,7 @@ export const addToPlaylistDialogReducer = ( ...previousState, open: true, selectedIds: payload.selectedIds, + albumIds: payload.albumIds, onSuccess: payload.onSuccess, } case ADD_TO_PLAYLIST_CLOSE: