Add "Play Next" action (finally)
This commit is contained in:
@@ -22,8 +22,9 @@
|
|||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
"addToQueue": "Adicionar à fila",
|
"addToQueue": "Adicionar à fila",
|
||||||
"playNow": "Tocar agora",
|
|
||||||
"addToPlaylist": "Adicionar à playlist",
|
"addToPlaylist": "Adicionar à playlist",
|
||||||
|
"playNow": "Tocar agora",
|
||||||
|
"playNext": "Toca a seguir",
|
||||||
"shuffleAll": "Aleatório",
|
"shuffleAll": "Aleatório",
|
||||||
"download": "Baixar"
|
"download": "Baixar"
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+24
-3
@@ -14031,6 +14031,13 @@
|
|||||||
"tough-cookie": "~2.5.0",
|
"tough-cookie": "~2.5.0",
|
||||||
"tunnel-agent": "^0.6.0",
|
"tunnel-agent": "^0.6.0",
|
||||||
"uuid": "^3.3.2"
|
"uuid": "^3.3.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"request-promise-core": {
|
"request-promise-core": {
|
||||||
@@ -14842,6 +14849,13 @@
|
|||||||
"faye-websocket": "^0.10.0",
|
"faye-websocket": "^0.10.0",
|
||||||
"uuid": "^3.4.0",
|
"uuid": "^3.4.0",
|
||||||
"websocket-driver": "0.6.5"
|
"websocket-driver": "0.6.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sockjs-client": {
|
"sockjs-client": {
|
||||||
@@ -16135,9 +16149,9 @@
|
|||||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||||
},
|
},
|
||||||
"uuid": {
|
"uuid": {
|
||||||
"version": "3.4.0",
|
"version": "8.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz",
|
||||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
"integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ=="
|
||||||
},
|
},
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
@@ -16685,6 +16699,13 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"ansi-colors": "^3.0.0",
|
"ansi-colors": "^3.0.0",
|
||||||
"uuid": "^3.3.2"
|
"uuid": "^3.3.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"webpack-manifest-plugin": {
|
"webpack-manifest-plugin": {
|
||||||
|
|||||||
+3
-1
@@ -17,11 +17,13 @@
|
|||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-drag-listview": "^0.1.7",
|
"react-drag-listview": "^0.1.7",
|
||||||
"react-ga": "^3.1.2",
|
"react-ga": "^3.1.2",
|
||||||
|
"react-icons": "^3.11.0",
|
||||||
"react-image-lightbox": "^5.1.1",
|
"react-image-lightbox": "^5.1.1",
|
||||||
"react-jinke-music-player": "^4.18.2",
|
"react-jinke-music-player": "^4.18.2",
|
||||||
"react-measure": "^2.5.2",
|
"react-measure": "^2.5.2",
|
||||||
"react-redux": "^7.2.1",
|
"react-redux": "^7.2.1",
|
||||||
"react-scripts": "^3.4.3"
|
"react-scripts": "^3.4.3",
|
||||||
|
"uuid": "^8.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@testing-library/jest-dom": "^5.11.4",
|
"@testing-library/jest-dom": "^5.11.4",
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import {
|
|||||||
import PlayArrowIcon from '@material-ui/icons/PlayArrow'
|
import PlayArrowIcon from '@material-ui/icons/PlayArrow'
|
||||||
import ShuffleIcon from '@material-ui/icons/Shuffle'
|
import ShuffleIcon from '@material-ui/icons/Shuffle'
|
||||||
import CloudDownloadOutlinedIcon from '@material-ui/icons/CloudDownloadOutlined'
|
import CloudDownloadOutlinedIcon from '@material-ui/icons/CloudDownloadOutlined'
|
||||||
import AddToQueueIcon from '@material-ui/icons/AddToQueue'
|
import { RiPlayListAddFill, RiPlayList2Fill } from 'react-icons/ri'
|
||||||
import { addTracks, playTracks, shuffleTracks } from '../audioplayer'
|
import { playNext, addTracks, playTracks, shuffleTracks } from '../audioplayer'
|
||||||
import subsonic from '../subsonic'
|
import subsonic from '../subsonic'
|
||||||
|
|
||||||
const AlbumActions = ({ className, ids, data, record, ...rest }) => {
|
const AlbumActions = ({ className, ids, data, record, ...rest }) => {
|
||||||
@@ -22,6 +22,10 @@ const AlbumActions = ({ className, ids, data, record, ...rest }) => {
|
|||||||
dispatch(playTracks(data, ids))
|
dispatch(playTracks(data, ids))
|
||||||
}, [dispatch, data, ids])
|
}, [dispatch, data, ids])
|
||||||
|
|
||||||
|
const handlePlayNext = React.useCallback(() => {
|
||||||
|
dispatch(playNext(data, ids))
|
||||||
|
}, [dispatch, data, ids])
|
||||||
|
|
||||||
const handlePlayLater = React.useCallback(() => {
|
const handlePlayLater = React.useCallback(() => {
|
||||||
dispatch(addTracks(data, ids))
|
dispatch(addTracks(data, ids))
|
||||||
}, [dispatch, data, ids])
|
}, [dispatch, data, ids])
|
||||||
@@ -48,11 +52,17 @@ const AlbumActions = ({ className, ids, data, record, ...rest }) => {
|
|||||||
>
|
>
|
||||||
<ShuffleIcon />
|
<ShuffleIcon />
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handlePlayNext}
|
||||||
|
label={translate('resources.album.actions.playNext')}
|
||||||
|
>
|
||||||
|
<RiPlayList2Fill />
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={handlePlayLater}
|
onClick={handlePlayLater}
|
||||||
label={translate('resources.album.actions.addToQueue')}
|
label={translate('resources.album.actions.addToQueue')}
|
||||||
>
|
>
|
||||||
<AddToQueueIcon />
|
<RiPlayListAddFill />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleDownload}
|
onClick={handleDownload}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React, { Fragment, useEffect } from 'react'
|
import React, { Fragment, useEffect } from 'react'
|
||||||
import { useUnselectAll } from 'react-admin'
|
import { useUnselectAll } from 'react-admin'
|
||||||
|
import { playNext } from '../audioplayer'
|
||||||
import AddToQueueButton from '../song/AddToQueueButton'
|
import AddToQueueButton from '../song/AddToQueueButton'
|
||||||
import AddToPlaylistButton from '../song/AddToPlaylistButton'
|
import AddToPlaylistButton from '../song/AddToPlaylistButton'
|
||||||
|
|
||||||
@@ -11,6 +12,11 @@ export const AlbumSongBulkActions = (props) => {
|
|||||||
}, [])
|
}, [])
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
<AddToQueueButton
|
||||||
|
{...props}
|
||||||
|
action={playNext}
|
||||||
|
label={'resources.song.actions.playNext'}
|
||||||
|
/>
|
||||||
<AddToQueueButton {...props} />
|
<AddToQueueButton {...props} />
|
||||||
<AddToPlaylistButton {...props} />
|
<AddToPlaylistButton {...props} />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ const Player = () => {
|
|||||||
return (
|
return (
|
||||||
<ReactJkMusicPlayer
|
<ReactJkMusicPlayer
|
||||||
{...options}
|
{...options}
|
||||||
|
quietUpdate
|
||||||
onAudioListsChange={OnAudioListsChange}
|
onAudioListsChange={OnAudioListsChange}
|
||||||
onAudioProgress={OnAudioProgress}
|
onAudioProgress={OnAudioProgress}
|
||||||
onAudioPlay={OnAudioPlay}
|
onAudioPlay={OnAudioPlay}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
setTrack,
|
setTrack,
|
||||||
playQueueReducer,
|
playQueueReducer,
|
||||||
playTracks,
|
playTracks,
|
||||||
|
playNext,
|
||||||
shuffleTracks,
|
shuffleTracks,
|
||||||
clearQueue,
|
clearQueue,
|
||||||
} from './queue'
|
} from './queue'
|
||||||
@@ -13,6 +14,7 @@ export {
|
|||||||
addTracks,
|
addTracks,
|
||||||
setTrack,
|
setTrack,
|
||||||
playTracks,
|
playTracks,
|
||||||
|
playNext,
|
||||||
playQueueReducer,
|
playQueueReducer,
|
||||||
shuffleTracks,
|
shuffleTracks,
|
||||||
clearQueue,
|
clearQueue,
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import 'react-jinke-music-player/assets/index.css'
|
import 'react-jinke-music-player/assets/index.css'
|
||||||
|
import get from 'lodash.get'
|
||||||
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import subsonic from '../subsonic'
|
import subsonic from '../subsonic'
|
||||||
|
|
||||||
const PLAYER_ADD_TRACKS = 'PLAYER_ADD_TRACKS'
|
const PLAYER_ADD_TRACKS = 'PLAYER_ADD_TRACKS'
|
||||||
|
const PLAYER_PLAY_NEXT = 'PLAYER_PLAY_NEXT'
|
||||||
const PLAYER_SET_TRACK = 'PLAYER_SET_TRACK'
|
const PLAYER_SET_TRACK = 'PLAYER_SET_TRACK'
|
||||||
const PLAYER_SYNC_QUEUE = 'PLAYER_SYNC_QUEUE'
|
const PLAYER_SYNC_QUEUE = 'PLAYER_SYNC_QUEUE'
|
||||||
const PLAYER_CLEAR_QUEUE = 'PLAYER_CLEAR_QUEUE'
|
const PLAYER_CLEAR_QUEUE = 'PLAYER_CLEAR_QUEUE'
|
||||||
@@ -23,6 +26,7 @@ const mapToAudioLists = (item) => {
|
|||||||
cover: subsonic.url('getCoverArt', id, { size: 300 }),
|
cover: subsonic.url('getCoverArt', id, { size: 300 }),
|
||||||
musicSrc: subsonic.url('stream', id, { ts: true }),
|
musicSrc: subsonic.url('stream', id, { ts: true }),
|
||||||
scrobbled: false,
|
scrobbled: false,
|
||||||
|
uuid: uuidv4(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +50,14 @@ const addTracks = (data, ids) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const playNext = (data, ids) => {
|
||||||
|
const songs = filterSongs(data, ids)
|
||||||
|
return {
|
||||||
|
type: PLAYER_PLAY_NEXT,
|
||||||
|
data: songs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const shuffle = (data) => {
|
const shuffle = (data) => {
|
||||||
const ids = Object.keys(data)
|
const ids = Object.keys(data)
|
||||||
for (let i = ids.length - 1; i > 0; i--) {
|
for (let i = ids.length - 1; i > 0; i--) {
|
||||||
@@ -109,6 +121,7 @@ const initialState = { queue: [], clear: true, current: {}, volume: 1 }
|
|||||||
|
|
||||||
const playQueueReducer = (previousState = initialState, payload) => {
|
const playQueueReducer = (previousState = initialState, payload) => {
|
||||||
let queue, current
|
let queue, current
|
||||||
|
let newQueue
|
||||||
const { type, data } = payload
|
const { type, data } = payload
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PLAYER_CLEAR_QUEUE:
|
case PLAYER_CLEAR_QUEUE:
|
||||||
@@ -124,6 +137,7 @@ const playQueueReducer = (previousState = initialState, payload) => {
|
|||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
trackId: data.trackId,
|
trackId: data.trackId,
|
||||||
|
uuid: data.uuid,
|
||||||
paused: data.paused,
|
paused: data.paused,
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -137,6 +151,25 @@ const playQueueReducer = (previousState = initialState, payload) => {
|
|||||||
queue.push(mapToAudioLists(data[id]))
|
queue.push(mapToAudioLists(data[id]))
|
||||||
})
|
})
|
||||||
return { ...previousState, queue, clear: false }
|
return { ...previousState, queue, clear: false }
|
||||||
|
case PLAYER_PLAY_NEXT:
|
||||||
|
current = get(previousState.current, 'uuid', '')
|
||||||
|
newQueue = []
|
||||||
|
let foundPos = false
|
||||||
|
previousState.queue.forEach((item) => {
|
||||||
|
newQueue.push(item)
|
||||||
|
if (item.uuid === current) {
|
||||||
|
foundPos = true
|
||||||
|
Object.keys(data).forEach((id) => {
|
||||||
|
newQueue.push(mapToAudioLists(data[id]))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (!foundPos) {
|
||||||
|
Object.keys(data).forEach((id) => {
|
||||||
|
newQueue.push(mapToAudioLists(data[id]))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return { ...previousState, queue: newQueue, clear: true }
|
||||||
case PLAYER_SET_TRACK:
|
case PLAYER_SET_TRACK:
|
||||||
return {
|
return {
|
||||||
...previousState,
|
...previousState,
|
||||||
@@ -152,7 +185,7 @@ const playQueueReducer = (previousState = initialState, payload) => {
|
|||||||
current,
|
current,
|
||||||
}
|
}
|
||||||
case PLAYER_SCROBBLE:
|
case PLAYER_SCROBBLE:
|
||||||
const newQueue = previousState.queue.map((item) => {
|
newQueue = previousState.queue.map((item) => {
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
scrobbled:
|
scrobbled:
|
||||||
@@ -189,6 +222,7 @@ export {
|
|||||||
addTracks,
|
addTracks,
|
||||||
setTrack,
|
setTrack,
|
||||||
playTracks,
|
playTracks,
|
||||||
|
playNext,
|
||||||
syncQueue,
|
syncQueue,
|
||||||
clearQueue,
|
clearQueue,
|
||||||
scrobble,
|
scrobble,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import MenuItem from '@material-ui/core/MenuItem'
|
|||||||
import MoreVertIcon from '@material-ui/icons/MoreVert'
|
import MoreVertIcon from '@material-ui/icons/MoreVert'
|
||||||
import { makeStyles } from '@material-ui/core/styles'
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import { useDataProvider, useNotify, useTranslate } from 'react-admin'
|
import { useDataProvider, useNotify, useTranslate } from 'react-admin'
|
||||||
import { addTracks, playTracks, shuffleTracks } from '../audioplayer'
|
import { playNext, addTracks, playTracks, shuffleTracks } from '../audioplayer'
|
||||||
import { openAddToPlaylist } from '../dialogs/dialogState'
|
import { openAddToPlaylist } from '../dialogs/dialogState'
|
||||||
import subsonic from '../subsonic'
|
import subsonic from '../subsonic'
|
||||||
import StarButton from './StarButton'
|
import StarButton from './StarButton'
|
||||||
@@ -43,6 +43,11 @@ const ContextMenu = ({
|
|||||||
label: 'resources.album.actions.playAll',
|
label: 'resources.album.actions.playAll',
|
||||||
action: (data, ids) => dispatch(playTracks(data, ids)),
|
action: (data, ids) => dispatch(playTracks(data, ids)),
|
||||||
},
|
},
|
||||||
|
playNext: {
|
||||||
|
needData: true,
|
||||||
|
label: 'resources.album.actions.playNext',
|
||||||
|
action: (data, ids) => dispatch(playNext(data, ids)),
|
||||||
|
},
|
||||||
addToQueue: {
|
addToQueue: {
|
||||||
needData: true,
|
needData: true,
|
||||||
label: 'resources.album.actions.addToQueue',
|
label: 'resources.album.actions.addToQueue',
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useTranslate } from 'react-admin'
|
|||||||
import { IconButton, Menu, MenuItem } from '@material-ui/core'
|
import { IconButton, Menu, MenuItem } from '@material-ui/core'
|
||||||
import { makeStyles } from '@material-ui/core/styles'
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import MoreVertIcon from '@material-ui/icons/MoreVert'
|
import MoreVertIcon from '@material-ui/icons/MoreVert'
|
||||||
import { addTracks, setTrack } from '../audioplayer'
|
import { playNext, addTracks, setTrack } from '../audioplayer'
|
||||||
import { openAddToPlaylist } from '../dialogs/dialogState'
|
import { openAddToPlaylist } from '../dialogs/dialogState'
|
||||||
import subsonic from '../subsonic'
|
import subsonic from '../subsonic'
|
||||||
import StarButton from './StarButton'
|
import StarButton from './StarButton'
|
||||||
@@ -35,6 +35,10 @@ const SongContextMenu = ({
|
|||||||
label: 'resources.song.actions.playNow',
|
label: 'resources.song.actions.playNow',
|
||||||
action: (record) => dispatch(setTrack(record)),
|
action: (record) => dispatch(setTrack(record)),
|
||||||
},
|
},
|
||||||
|
playNext: {
|
||||||
|
label: 'resources.song.actions.playNext',
|
||||||
|
action: (record) => dispatch(playNext({ [record.id]: record })),
|
||||||
|
},
|
||||||
addToQueue: {
|
addToQueue: {
|
||||||
label: 'resources.song.actions.addToQueue',
|
label: 'resources.song.actions.addToQueue',
|
||||||
action: (record) => dispatch(addTracks({ [record.id]: record })),
|
action: (record) => dispatch(addTracks({ [record.id]: record })),
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
"addToQueue": "Play Later",
|
"addToQueue": "Play Later",
|
||||||
"addToPlaylist": "Add to Playlist",
|
"addToPlaylist": "Add to Playlist",
|
||||||
"playNow": "Play Now",
|
"playNow": "Play Now",
|
||||||
|
"playNext": "Play Next",
|
||||||
"shuffleAll": "Shuffle All",
|
"shuffleAll": "Shuffle All",
|
||||||
"download": "Download"
|
"download": "Download"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import {
|
|||||||
import PlayArrowIcon from '@material-ui/icons/PlayArrow'
|
import PlayArrowIcon from '@material-ui/icons/PlayArrow'
|
||||||
import ShuffleIcon from '@material-ui/icons/Shuffle'
|
import ShuffleIcon from '@material-ui/icons/Shuffle'
|
||||||
import CloudDownloadOutlinedIcon from '@material-ui/icons/CloudDownloadOutlined'
|
import CloudDownloadOutlinedIcon from '@material-ui/icons/CloudDownloadOutlined'
|
||||||
import AddToQueueIcon from '@material-ui/icons/AddToQueue'
|
import { RiPlayListAddFill, RiPlayList2Fill } from 'react-icons/ri'
|
||||||
import QueueMusicIcon from '@material-ui/icons/QueueMusic'
|
import QueueMusicIcon from '@material-ui/icons/QueueMusic'
|
||||||
import { httpClient } from '../dataProvider'
|
import { httpClient } from '../dataProvider'
|
||||||
import { addTracks, playTracks, shuffleTracks } from '../audioplayer'
|
import { playNext, addTracks, playTracks, shuffleTracks } from '../audioplayer'
|
||||||
import { M3U_MIME_TYPE, REST_URL } from '../consts'
|
import { M3U_MIME_TYPE, REST_URL } from '../consts'
|
||||||
import subsonic from '../subsonic'
|
import subsonic from '../subsonic'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
@@ -25,6 +25,10 @@ const PlaylistActions = ({ className, ids, data, record, ...rest }) => {
|
|||||||
dispatch(playTracks(data, ids))
|
dispatch(playTracks(data, ids))
|
||||||
}, [dispatch, data, ids])
|
}, [dispatch, data, ids])
|
||||||
|
|
||||||
|
const handlePlayNext = React.useCallback(() => {
|
||||||
|
dispatch(playNext(data, ids))
|
||||||
|
}, [dispatch, data, ids])
|
||||||
|
|
||||||
const handlePlayLater = React.useCallback(() => {
|
const handlePlayLater = React.useCallback(() => {
|
||||||
dispatch(addTracks(data, ids))
|
dispatch(addTracks(data, ids))
|
||||||
}, [dispatch, data, ids])
|
}, [dispatch, data, ids])
|
||||||
@@ -69,11 +73,17 @@ const PlaylistActions = ({ className, ids, data, record, ...rest }) => {
|
|||||||
>
|
>
|
||||||
<ShuffleIcon />
|
<ShuffleIcon />
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handlePlayNext}
|
||||||
|
label={translate('resources.album.actions.playNext')}
|
||||||
|
>
|
||||||
|
<RiPlayList2Fill />
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={handlePlayLater}
|
onClick={handlePlayLater}
|
||||||
label={translate('resources.album.actions.addToQueue')}
|
label={translate('resources.album.actions.addToQueue')}
|
||||||
>
|
>
|
||||||
<AddToQueueIcon />
|
<RiPlayListAddFill />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleDownload}
|
onClick={handleDownload}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import {
|
|||||||
} from 'react-admin'
|
} from 'react-admin'
|
||||||
import { useDispatch } from 'react-redux'
|
import { useDispatch } from 'react-redux'
|
||||||
import { addTracks } from '../audioplayer'
|
import { addTracks } from '../audioplayer'
|
||||||
import AddToQueueIcon from '@material-ui/icons/AddToQueue'
|
import { RiPlayListAddFill } from 'react-icons/ri'
|
||||||
|
|
||||||
const AddToQueueButton = ({ resource, selectedIds }) => {
|
const AddToQueueButton = ({ resource, selectedIds, action, label, icon }) => {
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const translate = useTranslate()
|
const translate = useTranslate()
|
||||||
const dataProvider = useDataProvider()
|
const dataProvider = useDataProvider()
|
||||||
@@ -27,7 +27,7 @@ const AddToQueueButton = ({ resource, selectedIds }) => {
|
|||||||
{}
|
{}
|
||||||
)
|
)
|
||||||
// Add the tracks to the queue in the selection order
|
// Add the tracks to the queue in the selection order
|
||||||
dispatch(addTracks(tracks, selectedIds))
|
dispatch(action(tracks, selectedIds))
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
notify('ra.page.error', 'warning')
|
notify('ra.page.error', 'warning')
|
||||||
@@ -36,14 +36,16 @@ const AddToQueueButton = ({ resource, selectedIds }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button color="secondary" onClick={addToQueue} label={translate(label)}>
|
||||||
color="secondary"
|
{icon}
|
||||||
onClick={addToQueue}
|
|
||||||
label={translate('resources.song.actions.addToQueue')}
|
|
||||||
>
|
|
||||||
<AddToQueueIcon />
|
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddToQueueButton.defaultProps = {
|
||||||
|
action: addTracks,
|
||||||
|
label: 'resources.song.actions.addToQueue',
|
||||||
|
icon: <RiPlayListAddFill />,
|
||||||
|
}
|
||||||
|
|
||||||
export default AddToQueueButton
|
export default AddToQueueButton
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
import React, { Fragment } from 'react'
|
import React, { Fragment } from 'react'
|
||||||
import AddToQueueButton from './AddToQueueButton'
|
import AddToQueueButton from './AddToQueueButton'
|
||||||
import AddToPlaylistButton from './AddToPlaylistButton'
|
import AddToPlaylistButton from './AddToPlaylistButton'
|
||||||
|
import { RiPlayList2Fill } from 'react-icons/ri'
|
||||||
|
import { playNext } from '../audioplayer'
|
||||||
|
|
||||||
export const SongBulkActions = (props) => {
|
export const SongBulkActions = (props) => {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
<AddToQueueButton
|
||||||
|
{...props}
|
||||||
|
action={playNext}
|
||||||
|
label={'resources.song.actions.playNext'}
|
||||||
|
icon={<RiPlayList2Fill />}
|
||||||
|
/>
|
||||||
<AddToQueueButton {...props} />
|
<AddToQueueButton {...props} />
|
||||||
<AddToPlaylistButton {...props} />
|
<AddToPlaylistButton {...props} />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|||||||
Reference in New Issue
Block a user