mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-18 21:07:44 +03:00
Add Playlist action
This commit is contained in:
parent
f881e2a54b
commit
fd49ae319f
@ -8,7 +8,7 @@ import PlayArrowIcon from '@material-ui/icons/PlayArrow'
|
|||||||
import ShuffleIcon from '@material-ui/icons/Shuffle'
|
import ShuffleIcon from '@material-ui/icons/Shuffle'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useDispatch } from 'react-redux'
|
import { useDispatch } from 'react-redux'
|
||||||
import { playAlbum, shuffleAlbum } from '../audioplayer'
|
import { playTracks, shuffleTracks } from '../audioplayer'
|
||||||
|
|
||||||
const AlbumActions = ({
|
const AlbumActions = ({
|
||||||
className,
|
className,
|
||||||
@ -25,7 +25,7 @@ const AlbumActions = ({
|
|||||||
<TopToolbar className={className} {...sanitizeListRestProps(rest)}>
|
<TopToolbar className={className} {...sanitizeListRestProps(rest)}>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
dispatch(playAlbum(data, ids))
|
dispatch(playTracks(data, ids))
|
||||||
}}
|
}}
|
||||||
label={translate('resources.album.actions.playAll')}
|
label={translate('resources.album.actions.playAll')}
|
||||||
>
|
>
|
||||||
@ -33,7 +33,7 @@ const AlbumActions = ({
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
dispatch(shuffleAlbum(data, ids))
|
dispatch(shuffleTracks(data, ids))
|
||||||
}}
|
}}
|
||||||
label={translate('resources.album.actions.shuffle')}
|
label={translate('resources.album.actions.shuffle')}
|
||||||
>
|
>
|
||||||
|
@ -6,7 +6,7 @@ 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 { useDispatch } from 'react-redux'
|
import { useDispatch } from 'react-redux'
|
||||||
import { addTracks, playAlbum, shuffleAlbum } from '../audioplayer'
|
import { addTracks, playTracks, shuffleTracks } from '../audioplayer'
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles({
|
||||||
icon: {
|
icon: {
|
||||||
@ -25,7 +25,7 @@ const AlbumContextMenu = ({ record, color }) => {
|
|||||||
const options = {
|
const options = {
|
||||||
play: {
|
play: {
|
||||||
label: translate('resources.album.actions.playAll'),
|
label: translate('resources.album.actions.playAll'),
|
||||||
action: (data) => playAlbum(data),
|
action: (data) => playTracks(data),
|
||||||
},
|
},
|
||||||
addToQueue: {
|
addToQueue: {
|
||||||
label: translate('resources.album.actions.addToQueue'),
|
label: translate('resources.album.actions.addToQueue'),
|
||||||
@ -33,7 +33,7 @@ const AlbumContextMenu = ({ record, color }) => {
|
|||||||
},
|
},
|
||||||
shuffle: {
|
shuffle: {
|
||||||
label: translate('resources.album.actions.shuffle'),
|
label: translate('resources.album.actions.shuffle'),
|
||||||
action: (data) => shuffleAlbum(data),
|
action: (data) => shuffleTracks(data),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import classnames from 'classnames'
|
|||||||
import { useDispatch } from 'react-redux'
|
import { useDispatch } from 'react-redux'
|
||||||
import { Card, useMediaQuery } from '@material-ui/core'
|
import { Card, useMediaQuery } from '@material-ui/core'
|
||||||
import { makeStyles } from '@material-ui/core/styles'
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import { playAlbum } from '../audioplayer'
|
import { playTracks } from '../audioplayer'
|
||||||
import { DurationField, SongDetails, SongDatagridRow } from '../common'
|
import { DurationField, SongDetails, SongDatagridRow } from '../common'
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
@ -124,7 +124,7 @@ const AlbumSongs = (props) => {
|
|||||||
) : (
|
) : (
|
||||||
<SongsDatagrid
|
<SongsDatagrid
|
||||||
expand={!isXsmall && <SongDetails />}
|
expand={!isXsmall && <SongDetails />}
|
||||||
rowClick={(id) => dispatch(playAlbum(data, ids, id))}
|
rowClick={(id) => dispatch(playTracks(data, ids, id))}
|
||||||
{...controllerProps}
|
{...controllerProps}
|
||||||
hasBulkActions={hasBulkActions}
|
hasBulkActions={hasBulkActions}
|
||||||
>
|
>
|
||||||
|
@ -3,15 +3,15 @@ import {
|
|||||||
addTracks,
|
addTracks,
|
||||||
setTrack,
|
setTrack,
|
||||||
playQueueReducer,
|
playQueueReducer,
|
||||||
playAlbum,
|
playTracks,
|
||||||
shuffleAlbum,
|
shuffleTracks,
|
||||||
} from './queue'
|
} from './queue'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Player,
|
Player,
|
||||||
addTracks,
|
addTracks,
|
||||||
setTrack,
|
setTrack,
|
||||||
playAlbum,
|
playTracks,
|
||||||
playQueueReducer,
|
playQueueReducer,
|
||||||
shuffleAlbum,
|
shuffleTracks,
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,19 @@ const PLAYER_SYNC_QUEUE = 'PLAYER_SYNC_QUEUE'
|
|||||||
const PLAYER_SCROBBLE = 'PLAYER_SCROBBLE'
|
const PLAYER_SCROBBLE = 'PLAYER_SCROBBLE'
|
||||||
const PLAYER_PLAY_ALBUM = 'PLAYER_PLAY_ALBUM'
|
const PLAYER_PLAY_ALBUM = 'PLAYER_PLAY_ALBUM'
|
||||||
|
|
||||||
const mapToAudioLists = (item) => ({
|
const mapToAudioLists = (item) => {
|
||||||
id: item.id,
|
// If item comes from a playlist, id is mediaFileId
|
||||||
trackId: item.id,
|
const id = item.mediaFileId || item.id
|
||||||
name: item.title,
|
return {
|
||||||
singer: item.artist,
|
trackId: id,
|
||||||
duration: item.duration,
|
name: item.title,
|
||||||
cover: subsonic.url('getCoverArt', item.id, { size: 300 }),
|
singer: item.artist,
|
||||||
musicSrc: subsonic.url('stream', item.id, { ts: true }),
|
duration: item.duration,
|
||||||
scrobbled: false,
|
cover: subsonic.url('getCoverArt', id, { size: 300 }),
|
||||||
})
|
musicSrc: subsonic.url('stream', id, { ts: true }),
|
||||||
|
scrobbled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const setTrack = (data) => ({
|
const setTrack = (data) => ({
|
||||||
type: PLAYER_SET_TRACK,
|
type: PLAYER_SET_TRACK,
|
||||||
@ -49,7 +52,7 @@ const shuffle = (data) => {
|
|||||||
return shuffled
|
return shuffled
|
||||||
}
|
}
|
||||||
|
|
||||||
const shuffleAlbum = (data, ids) => {
|
const shuffleTracks = (data, ids) => {
|
||||||
const songs = filterAlbumSongs(data, ids)
|
const songs = filterAlbumSongs(data, ids)
|
||||||
const shuffled = shuffle(songs)
|
const shuffled = shuffle(songs)
|
||||||
const firstId = Object.keys(shuffled)[0]
|
const firstId = Object.keys(shuffled)[0]
|
||||||
@ -60,7 +63,7 @@ const shuffleAlbum = (data, ids) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const playAlbum = (data, ids, selectedId) => {
|
const playTracks = (data, ids, selectedId) => {
|
||||||
const songs = filterAlbumSongs(data, ids)
|
const songs = filterAlbumSongs(data, ids)
|
||||||
return {
|
return {
|
||||||
type: PLAYER_PLAY_ALBUM,
|
type: PLAYER_PLAY_ALBUM,
|
||||||
@ -146,9 +149,9 @@ const playQueueReducer = (
|
|||||||
export {
|
export {
|
||||||
addTracks,
|
addTracks,
|
||||||
setTrack,
|
setTrack,
|
||||||
playAlbum,
|
playTracks,
|
||||||
syncQueue,
|
syncQueue,
|
||||||
scrobble,
|
scrobble,
|
||||||
shuffleAlbum,
|
shuffleTracks,
|
||||||
playQueueReducer,
|
playQueueReducer,
|
||||||
}
|
}
|
||||||
|
42
ui/src/playlist/PlaylistActions.js
Normal file
42
ui/src/playlist/PlaylistActions.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import {
|
||||||
|
Button,
|
||||||
|
sanitizeListRestProps,
|
||||||
|
TopToolbar,
|
||||||
|
useTranslate,
|
||||||
|
} from 'react-admin'
|
||||||
|
import PlayArrowIcon from '@material-ui/icons/PlayArrow'
|
||||||
|
import React from 'react'
|
||||||
|
import { useDispatch } from 'react-redux'
|
||||||
|
import { playTracks } from '../audioplayer'
|
||||||
|
|
||||||
|
const PlaylistActions = ({
|
||||||
|
className,
|
||||||
|
ids,
|
||||||
|
data,
|
||||||
|
exporter,
|
||||||
|
permanentFilter,
|
||||||
|
...rest
|
||||||
|
}) => {
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
const translate = useTranslate()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TopToolbar className={className} {...sanitizeListRestProps(rest)}>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
dispatch(playTracks(data))
|
||||||
|
}}
|
||||||
|
label={translate('resources.album.actions.playAll')}
|
||||||
|
>
|
||||||
|
<PlayArrowIcon />
|
||||||
|
</Button>
|
||||||
|
</TopToolbar>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
PlaylistActions.defaultProps = {
|
||||||
|
selectedIds: [],
|
||||||
|
onUnselectItems: () => null,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PlaylistActions
|
@ -3,6 +3,7 @@ import { useGetOne } from 'react-admin'
|
|||||||
import PlaylistDetails from './PlaylistDetails'
|
import PlaylistDetails from './PlaylistDetails'
|
||||||
import { Title } from '../common'
|
import { Title } from '../common'
|
||||||
import PlaylistSongs from './PlaylistSongs'
|
import PlaylistSongs from './PlaylistSongs'
|
||||||
|
import PlaylistActions from './PlaylistActions'
|
||||||
|
|
||||||
const PlaylistShow = (props) => {
|
const PlaylistShow = (props) => {
|
||||||
const { data: record, loading, error } = useGetOne('playlist', props.id)
|
const { data: record, loading, error } = useGetOne('playlist', props.id)
|
||||||
@ -22,7 +23,7 @@ const PlaylistShow = (props) => {
|
|||||||
{...props}
|
{...props}
|
||||||
playlistId={props.id}
|
playlistId={props.id}
|
||||||
title={<Title subTitle={record.name} />}
|
title={<Title subTitle={record.name} />}
|
||||||
// actions={<AlbumActions />}
|
actions={<PlaylistActions />}
|
||||||
filter={{ playlist_id: props.id }}
|
filter={{ playlist_id: props.id }}
|
||||||
resource={'playlistTrack'}
|
resource={'playlistTrack'}
|
||||||
exporter={false}
|
exporter={false}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user