mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-14 11:17:19 +03:00
Use redux for ShareDialog
This commit is contained in:
parent
17d9573f4d
commit
051e9c556d
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
@ -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 />
|
||||
</>
|
||||
)
|
||||
|
@ -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>
|
||||
)
|
||||
|
@ -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>
|
||||
)
|
||||
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user