Use redux for ShareDialog

This commit is contained in:
Deluan 2023-01-24 13:04:00 -05:00
parent 17d9573f4d
commit 051e9c556d
9 changed files with 113 additions and 56 deletions

View File

@ -29,6 +29,7 @@ import {
settingsReducer,
replayGainReducer,
downloadMenuDialogReducer,
shareDialogReducer,
} from './reducers'
import createAdminStore from './store/createAdminStore'
import { i18nProvider } from './i18n'
@ -60,6 +61,7 @@ const adminStore = createAdminStore({
downloadMenuDialog: downloadMenuDialogReducer,
expandInfoDialog: expandInfoDialogReducer,
listenBrainzTokenDialog: listenBrainzTokenDialogReducer,
shareDialog: shareDialogReducer,
activity: activityReducer,
settings: settingsReducer,
replayGain: replayGainReducer,

View File

@ -12,6 +12,19 @@ export const DOWNLOAD_MENU_ALBUM = 'album'
export const DOWNLOAD_MENU_ARTIST = 'artist'
export const DOWNLOAD_MENU_PLAY = 'playlist'
export const DOWNLOAD_MENU_SONG = 'song'
export const SHARE_MENU_OPEN = 'SHARE_MENU_OPEN'
export const SHARE_MENU_CLOSE = 'SHARE_MENU_CLOSE'
export const openShareMenu = (ids, resource, name) => ({
type: SHARE_MENU_OPEN,
ids,
resource,
name,
})
export const closeShareMenu = () => ({
type: SHARE_MENU_CLOSE,
})
export const openAddToPlaylist = ({ selectedIds, onSuccess }) => ({
type: ADD_TO_PLAYLIST_OPEN,

View File

@ -7,11 +7,13 @@ import {
TopToolbar,
useTranslate,
} from 'react-admin'
import { useMediaQuery, makeStyles } from '@material-ui/core'
import PlayArrowIcon from '@material-ui/icons/PlayArrow'
import ShuffleIcon from '@material-ui/icons/Shuffle'
import CloudDownloadOutlinedIcon from '@material-ui/icons/CloudDownloadOutlined'
import { RiPlayListAddFill, RiPlayList2Fill } from 'react-icons/ri'
import PlaylistAddIcon from '@material-ui/icons/PlaylistAdd'
import ShareIcon from '@material-ui/icons/Share'
import {
playNext,
addTracks,
@ -20,14 +22,11 @@ import {
openAddToPlaylist,
openDownloadMenu,
DOWNLOAD_MENU_ALBUM,
openShareMenu,
} from '../actions'
import { formatBytes } from '../utils'
import { useMediaQuery, makeStyles } from '@material-ui/core'
import config from '../config'
import { ToggleFieldsMenu } from '../common'
import { useDialog } from '../dialogs/useDialog'
import { ShareDialog } from '../dialogs/ShareDialog'
import ShareIcon from '@material-ui/icons/Share'
const useStyles = makeStyles({
toolbar: { display: 'flex', justifyContent: 'space-between', width: '100%' },
@ -38,6 +37,7 @@ const AlbumActions = ({
ids,
data,
record,
resource,
permanentFilter,
...rest
}) => {
@ -46,7 +46,6 @@ const AlbumActions = ({
const classes = useStyles()
const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))
const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))
const shareDialog = useDialog()
const handlePlay = React.useCallback(() => {
dispatch(playTracks(data, ids))
@ -68,6 +67,10 @@ const AlbumActions = ({
dispatch(openAddToPlaylist({ selectedIds: ids }))
}, [dispatch, ids])
const handleShare = React.useCallback(() => {
dispatch(openShareMenu([record.id], resource, record.name))
}, [dispatch, record, resource])
const handleDownload = React.useCallback(() => {
dispatch(openDownloadMenu(record, DOWNLOAD_MENU_ALBUM))
}, [dispatch, record])
@ -107,10 +110,7 @@ const AlbumActions = ({
<PlaylistAddIcon />
</Button>
{config.devEnableShare && (
<Button
onClick={shareDialog.openDialog}
label={translate('ra.action.share')}
>
<Button onClick={handleShare} label={translate('ra.action.share')}>
<ShareIcon />
</Button>
)}
@ -128,12 +128,6 @@ const AlbumActions = ({
</div>
<div>{isNotSmall && <ToggleFieldsMenu resource="albumSong" />}</div>
</div>
<ShareDialog
{...shareDialog.props}
ids={[record.id]}
resource={'album'}
name={record.name}
/>
</TopToolbar>
)
}

View File

@ -1,11 +1,13 @@
import { AddToPlaylistDialog } from './AddToPlaylistDialog'
import DownloadMenuDialog from './DownloadMenuDialog'
import { HelpDialog } from './HelpDialog'
import { ShareDialog } from './ShareDialog'
export const Dialogs = (props) => (
<>
<AddToPlaylistDialog />
<DownloadMenuDialog />
<HelpDialog />
<ShareDialog />
</>
)

View File

@ -67,12 +67,12 @@ const DownloadMenuDialog = () => {
</SimpleForm>
</DialogContent>
<DialogActions>
<Button onClick={handleDownload} color="primary">
{translate('ra.action.download')}
</Button>
<Button onClick={handleClose} color="secondary">
{translate('ra.action.close')}
</Button>
<Button onClick={handleDownload} color="primary">
{translate('ra.action.download')}
</Button>
</DialogActions>
</Dialog>
)

View File

@ -15,8 +15,14 @@ import {
import { useState } from 'react'
import { shareUrl } from '../utils'
import { useTranscodingOptions } from './useTranscodingOptions'
import { useDispatch, useSelector } from 'react-redux'
import { closeShareMenu } from '../actions'
export const ShareDialog = ({ open, onClose, ids, resource, name }) => {
export const ShareDialog = () => {
const { open, ids, resource, name } = useSelector(
(state) => state.shareDialog
)
const dispatch = useDispatch()
const notify = useNotify()
const translate = useTranslate()
const [description, setDescription] = useState('')
@ -34,15 +40,10 @@ export const ShareDialog = ({ open, onClose, ids, resource, name }) => {
{
onSuccess: (res) => {
const url = shareUrl(res?.data?.id)
onClose()
navigator.clipboard
.writeText(url)
.then(() => {
notify(translate('message.shareSuccess', { url }), {
type: 'info',
multiLine: true,
duration: 0,
})
notify('message.shareSuccess', 'info', { url }, false, 0)
})
.catch((err) => {
notify(
@ -56,26 +57,40 @@ export const ShareDialog = ({ open, onClose, ids, resource, name }) => {
})
},
onFailure: (error) =>
notify(`Error sharing media: ${error.message}`, { type: 'warning' }),
notify(translate('ra.page.error') + ': ' + error.message, {
type: 'warning',
}),
}
)
const handleShare = (e) => {
createShare()
dispatch(closeShareMenu())
e.stopPropagation()
}
const handleClose = (e) => {
dispatch(closeShareMenu())
e.stopPropagation()
}
return (
<Dialog
open={open}
onClose={onClose}
onBackdropClick={onClose}
onClose={handleClose}
onBackdropClick={handleClose}
aria-labelledby="share-dialog"
fullWidth={true}
maxWidth={'sm'}
>
<DialogTitle id="share-dialog">
{translate('message.shareDialogTitle', {
resource: translate(`resources.${resource}.name`, {
smart_count: ids?.length,
}).toLocaleLowerCase(),
name,
})}
{resource &&
translate('message.shareDialogTitle', {
resource: translate(`resources.${resource}.name`, {
smart_count: ids?.length,
}).toLocaleLowerCase(),
name,
})}
</DialogTitle>
<DialogContent>
<SimpleForm toolbar={null} variant={'outlined'}>
@ -93,12 +108,12 @@ export const ShareDialog = ({ open, onClose, ids, resource, name }) => {
</SimpleForm>
</DialogContent>
<DialogActions>
<Button onClick={createShare} color="primary">
{translate('ra.action.share')}
</Button>
<Button onClick={onClose} color="primary">
<Button onClick={handleClose} color="primary">
{translate('ra.action.close')}
</Button>
<Button onClick={handleShare} color="primary">
{translate('ra.action.share')}
</Button>
</DialogActions>
</Dialog>
)

View File

@ -8,11 +8,13 @@ import {
useDataProvider,
useNotify,
} from 'react-admin'
import { useMediaQuery, makeStyles } from '@material-ui/core'
import PlayArrowIcon from '@material-ui/icons/PlayArrow'
import ShuffleIcon from '@material-ui/icons/Shuffle'
import CloudDownloadOutlinedIcon from '@material-ui/icons/CloudDownloadOutlined'
import { RiPlayListAddFill, RiPlayList2Fill } from 'react-icons/ri'
import QueueMusicIcon from '@material-ui/icons/QueueMusic'
import ShareIcon from '@material-ui/icons/Share'
import { httpClient } from '../dataProvider'
import {
playNext,
@ -21,22 +23,26 @@ import {
shuffleTracks,
openDownloadMenu,
DOWNLOAD_MENU_PLAY,
openShareMenu,
} from '../actions'
import { M3U_MIME_TYPE, REST_URL } from '../consts'
import PropTypes from 'prop-types'
import { formatBytes } from '../utils'
import { useMediaQuery, makeStyles } from '@material-ui/core'
import config from '../config'
import { ToggleFieldsMenu } from '../common'
import { ShareDialog } from '../dialogs/ShareDialog'
import { useDialog } from '../dialogs/useDialog'
import ShareIcon from '@material-ui/icons/Share'
const useStyles = makeStyles({
toolbar: { display: 'flex', justifyContent: 'space-between', width: '100%' },
})
const PlaylistActions = ({ className, ids, data, record, ...rest }) => {
const PlaylistActions = ({
className,
ids,
data,
record,
resource,
...rest
}) => {
const dispatch = useDispatch()
const translate = useTranslate()
const classes = useStyles()
@ -44,7 +50,6 @@ const PlaylistActions = ({ className, ids, data, record, ...rest }) => {
const notify = useNotify()
const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))
const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))
const shareDialog = useDialog()
const getAllSongsAndDispatch = React.useCallback(
(action) => {
@ -88,6 +93,10 @@ const PlaylistActions = ({ className, ids, data, record, ...rest }) => {
getAllSongsAndDispatch(shuffleTracks)
}, [getAllSongsAndDispatch])
const handleShare = React.useCallback(() => {
dispatch(openShareMenu([record.id], resource, record.name))
}, [dispatch, record, resource])
const handleDownload = React.useCallback(() => {
dispatch(openDownloadMenu(record, DOWNLOAD_MENU_PLAY))
}, [dispatch, record])
@ -138,10 +147,7 @@ const PlaylistActions = ({ className, ids, data, record, ...rest }) => {
<RiPlayListAddFill />
</Button>
{config.devEnableShare && (
<Button
onClick={shareDialog.openDialog}
label={translate('ra.action.share')}
>
<Button onClick={handleShare} label={translate('ra.action.share')}>
<ShareIcon />
</Button>
)}
@ -165,12 +171,6 @@ const PlaylistActions = ({ className, ids, data, record, ...rest }) => {
</div>
<div>{isNotSmall && <ToggleFieldsMenu resource="playlistTrack" />}</div>
</div>
<ShareDialog
{...shareDialog.props}
ids={[record.id]}
resource={'playlist'}
name={record.name}
/>
</TopToolbar>
)
}

View File

@ -13,8 +13,39 @@ import {
EXTENDED_INFO_CLOSE,
LISTENBRAINZ_TOKEN_OPEN,
LISTENBRAINZ_TOKEN_CLOSE,
SHARE_MENU_OPEN,
SHARE_MENU_CLOSE,
} from '../actions'
export const shareDialogReducer = (
previousState = {
open: false,
ids: [],
resource: '',
name: '',
},
payload
) => {
const { type, ids, resource, name } = payload
switch (type) {
case SHARE_MENU_OPEN:
return {
...previousState,
open: true,
ids,
resource,
name,
}
case SHARE_MENU_CLOSE:
return {
...previousState,
open: false,
}
default:
return previousState
}
}
export const addToPlaylistDialogReducer = (
previousState = {
open: false,

View File

@ -10,11 +10,11 @@ import { Link } from '@material-ui/core'
import { DateField } from '../common'
export const ShareEdit = (props) => {
const { id } = props
const { id, basePath, hasCreate, ...rest } = props
const url = shareUrl(id)
return (
<Edit {...props}>
<SimpleForm>
<SimpleForm {...rest}>
<Link source="URL" href={url} target="_blank" rel="noopener noreferrer">
{url}
</Link>