Skip to content

Commit

Permalink
First version of dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
deluan committed May 26, 2020
1 parent 8973477 commit 23bd5e1
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 28 deletions.
2 changes: 2 additions & 0 deletions ui/src/App.js
Expand Up @@ -17,6 +17,7 @@ import { albumViewReducer } from './album/albumState'
import config from './config'
import customRoutes from './routes'
import themeReducer from './personal/themeReducer'
import { newPlaylistDialogReducer } from './dialogs/dialogState'
import createAdminStore from './store/createAdminStore'
import { i18nProvider } from './i18n'

Expand All @@ -32,6 +33,7 @@ const App = () => (
queue: playQueueReducer,
albumView: albumViewReducer,
theme: themeReducer,
newPlaylistDialog: newPlaylistDialogReducer,
},
})}
>
Expand Down
68 changes: 41 additions & 27 deletions ui/src/common/AddToPlaylistMenu.js
@@ -1,12 +1,16 @@
import React from 'react'
import { useDispatch } from 'react-redux'
import PropTypes from 'prop-types'
import {
useDataProvider,
useGetList,
useNotify,
useTranslate,
} from 'react-admin'
import { MenuItem } from '@material-ui/core'
import PropTypes from 'prop-types'
import { MenuItem, Divider } from '@material-ui/core'
import NewPlaylistIcon from '@material-ui/icons/Add'
import { openNewPlaylist } from '../dialogs/dialogState'
import NewPlaylistDialog from '../dialogs/NewPlaylist'

export const addTracksToPlaylist = (dataProvider, selectedIds, playlistId) =>
dataProvider
Expand All @@ -29,6 +33,7 @@ export const addAlbumToPlaylist = (dataProvider, albumId, playlistId) =>
const AddToPlaylistMenu = React.forwardRef(
({ selectedIds, albumId, onClose, onItemAdded }, ref) => {
const notify = useNotify()
const dispatch = useDispatch()
const translate = useTranslate()
const dataProvider = useDataProvider()
const { ids, data, loaded } = useGetList(
Expand All @@ -42,48 +47,55 @@ const AddToPlaylistMenu = React.forwardRef(
return <MenuItem>Loading...</MenuItem>
}

// TODO: This is temporary, while we don't have the "New Playlist" option in the menu
if (ids.length === 0) {
return (
<MenuItem
onClick={(e) => {
e.stopPropagation()
onClose && onClose(e)
}}
>
{translate('message.noPlaylistsAvailable')}
</MenuItem>
)
const addToPlaylist = (playlistId) => {
const add = albumId
? addAlbumToPlaylist(dataProvider, albumId, playlistId)
: addTracksToPlaylist(dataProvider, selectedIds, playlistId)

add
.then((len) => {
notify('message.songsAddedToPlaylist', 'info', { smart_count: len })
onItemAdded(playlistId)
})
.catch(() => {
notify('ra.page.error', 'warning')
})
}

const handleItemClick = (e) => {
e.preventDefault()
const playlistId = e.target.getAttribute('value')
if (playlistId !== '') {
const add = albumId
? addAlbumToPlaylist(dataProvider, albumId, playlistId)
: addTracksToPlaylist(dataProvider, selectedIds, playlistId)

add
.then((len) => {
notify('message.songsAddedToPlaylist', 'info', { smart_count: len })
onItemAdded && onItemAdded(playlistId, selectedIds)
})
.catch(() => {
notify('ra.page.error', 'warning')
})
addToPlaylist(playlistId)
}
e.stopPropagation()
onClose && onClose(e)
onClose(e)
}

const handleOpenDialog = (e) => {
e.preventDefault()
dispatch(openNewPlaylist(albumId, selectedIds))
e.stopPropagation()
onClose(e)
}

return (
<>
<Divider component="li" />
{ids.map((id) => (
<MenuItem value={id} key={id} onClick={handleItemClick}>
{data[id].name}
</MenuItem>
))}
<MenuItem
value="newPlaylist"
key="newPlaylist"
onClick={handleOpenDialog}
>
{<NewPlaylistIcon fontSize="small" />}&nbsp;
{translate('resources.playlist.actions.newPlaylist')}
</MenuItem>
<NewPlaylistDialog onSubmit={onItemAdded} />
</>
)
}
Expand All @@ -98,6 +110,8 @@ AddToPlaylistMenu.propTypes = {

AddToPlaylistMenu.defaultProps = {
selectedIds: [],
onClose: () => {},
onItemAdded: () => {},
}

export default AddToPlaylistMenu
120 changes: 120 additions & 0 deletions ui/src/dialogs/NewPlaylist.js
@@ -0,0 +1,120 @@
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import {
useCreate,
useDataProvider,
useTranslate,
useNotify,
} from 'react-admin'
import {
Button,
TextField,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
} from '@material-ui/core'
import PropTypes from 'prop-types'
import { closeNewPlaylist } from './dialogState'
import {
addAlbumToPlaylist,
addTracksToPlaylist,
} from '../common/AddToPlaylistMenu'

const NewPlaylistDialog = ({ onCancel, onSubmit }) => {
const { open, albumId, selectedIds } = useSelector(
(state) => state.newPlaylistDialog
)
const dispatch = useDispatch()
const translate = useTranslate()
const notify = useNotify()
const [value, setValue] = React.useState('')
const dataProvider = useDataProvider()
const [create] = useCreate(
'playlist',
{ name: value },
{
onSuccess: ({ data }) => {
addToPlaylist(data.id)
},
onFailure: (error) => notify(`Error: ${error.message}`, 'warning'),
}
)

const addToPlaylist = (playlistId) => {
const add = albumId
? addAlbumToPlaylist(dataProvider, albumId, playlistId)
: addTracksToPlaylist(dataProvider, selectedIds, playlistId)

add
.then((len) => {
notify('message.songsAddedToPlaylist', 'info', { smart_count: len })
onSubmit(value)
})
.catch(() => {
notify('ra.page.error', 'warning')
})
}

const handleSubmit = (e) => {
create()
dispatch(closeNewPlaylist())
e.stopPropagation()
}

const handleChange = (e) => {
setValue(e.target.value)
}

const handleClickClose = (e) => {
onCancel(e)
dispatch(closeNewPlaylist())
e.stopPropagation()
}

return (
<div>
<Dialog
disableBackdropClick
open={open}
onClose={handleClickClose}
aria-labelledby="form-dialog-new-playlist"
>
<DialogTitle id="form-dialog-new-playlist">
{translate('resources.playlist.actions.newPlaylist')}
</DialogTitle>
<DialogContent>
<TextField
autoFocus
margin="dense"
id="name"
label={translate('resources.playlist.fields.name')}
type="text"
fullWidth
onChange={handleChange}
/>
</DialogContent>
<DialogActions>
<Button onClick={handleClickClose} color="primary">
{translate('ra.action.cancel')}
</Button>
<Button onClick={handleSubmit} color="primary">
{translate('ra.action.create')}
</Button>
</DialogActions>
</Dialog>
</div>
)
}

NewPlaylistDialog.propTypes = {
onCancel: PropTypes.func,
onSubmit: PropTypes.func,
}

NewPlaylistDialog.defaultProps = {
onCancel: () => {},
onSubmit: () => {},
}

export default NewPlaylistDialog
36 changes: 36 additions & 0 deletions ui/src/dialogs/dialogState.js
@@ -0,0 +1,36 @@
const NEW_PLAYLIST_OPEN = 'NEW_PLAYLIST_OPEN'
const NEW_PLAYLIST_CLOSE = 'NEW_PLAYLIST_CLOSE'

const openNewPlaylist = (albumId, selectedIds) => ({
type: NEW_PLAYLIST_OPEN,
albumId,
selectedIds,
})

const closeNewPlaylist = () => ({
type: NEW_PLAYLIST_CLOSE,
})

const newPlaylistDialogReducer = (
previousState = {
open: false,
},
payload
) => {
const { type } = payload
switch (type) {
case NEW_PLAYLIST_OPEN:
return {
...previousState,
open: true,
albumId: payload.albumId,
selectedIds: payload.selectedIds,
}
case NEW_PLAYLIST_CLOSE:
return { ...previousState, open: false }
default:
return previousState
}
}

export { openNewPlaylist, closeNewPlaylist, newPlaylistDialogReducer }
3 changes: 2 additions & 1 deletion ui/src/i18n/en.json
Expand Up @@ -69,7 +69,8 @@
"createdAt": "Created at"
},
"actions": {
"selectPlaylist": "Add songs to playlist:"
"selectPlaylist": "Add songs to playlist:",
"newPlaylist": "New playlist"
}
},
"user": {
Expand Down

0 comments on commit 23bd5e1

Please sign in to comment.