feat: Add VideoKebabMenuButtons component
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import { Add, Cast, Delete, MoreVert, Share } from '@mui/icons-material';
|
||||
import { Button, IconButton, Menu, MenuItem, Stack, Tooltip, useMediaQuery, useTheme } from '@mui/material';
|
||||
import { Add, Cast, Delete, Share } from '@mui/icons-material';
|
||||
import { Button, Menu, MenuItem, Stack, Tooltip, useMediaQuery, useTheme } from '@mui/material';
|
||||
import React, { useState } from 'react';
|
||||
import { useLanguage } from '../../../contexts/LanguageContext';
|
||||
import { useSnackbar } from '../../../contexts/SnackbarContext';
|
||||
import { useShareVideo } from '../../../hooks/useShareVideo';
|
||||
import { Video } from '../../../types';
|
||||
import VideoKebabMenuButtons from './VideoKebabMenuButtons';
|
||||
|
||||
interface VideoActionButtonsProps {
|
||||
video: Video;
|
||||
@@ -25,7 +26,6 @@ const VideoActionButtons: React.FC<VideoActionButtonsProps> = ({
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
||||
const [playerMenuAnchor, setPlayerMenuAnchor] = useState<null | HTMLElement>(null);
|
||||
const [kebabMenuAnchor, setKebabMenuAnchor] = useState<null | HTMLElement>(null);
|
||||
|
||||
const getVideoUrl = (): string => {
|
||||
if (video.videoPath) {
|
||||
@@ -47,13 +47,6 @@ const VideoActionButtons: React.FC<VideoActionButtonsProps> = ({
|
||||
setPlayerMenuAnchor(null);
|
||||
};
|
||||
|
||||
const handleKebabMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setKebabMenuAnchor(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleKebabMenuClose = () => {
|
||||
setKebabMenuAnchor(null);
|
||||
};
|
||||
|
||||
const handlePlayerSelect = (player: string) => {
|
||||
const videoUrl = getVideoUrl();
|
||||
@@ -203,100 +196,13 @@ const VideoActionButtons: React.FC<VideoActionButtonsProps> = ({
|
||||
if (isMobile) {
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="More actions">
|
||||
<IconButton
|
||||
onClick={handleKebabMenuOpen}
|
||||
sx={{
|
||||
color: kebabMenuAnchor ? 'primary.main' : 'text.secondary',
|
||||
'&:hover': { color: 'primary.main' }
|
||||
}}
|
||||
>
|
||||
<MoreVert />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Menu
|
||||
anchorEl={kebabMenuAnchor}
|
||||
open={Boolean(kebabMenuAnchor)}
|
||||
onClose={handleKebabMenuClose}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'right',
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'right',
|
||||
}}
|
||||
slotProps={{
|
||||
paper: {
|
||||
sx: {
|
||||
minWidth: 'auto',
|
||||
p: 1,
|
||||
px: 2,
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Stack direction="row" spacing={2} sx={{ justifyContent: 'flex-end' }}>
|
||||
<Tooltip title={t('playWith')}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="inherit"
|
||||
onClick={() => {
|
||||
// Store the anchor before closing the kebab menu
|
||||
const anchor = kebabMenuAnchor;
|
||||
handleKebabMenuClose();
|
||||
// Use the stored anchor for the player menu
|
||||
if (anchor) {
|
||||
setPlayerMenuAnchor(anchor);
|
||||
}
|
||||
}}
|
||||
sx={{ minWidth: 'auto', p: 1, color: 'text.secondary', borderColor: 'text.secondary', '&:hover': { color: 'primary.main', borderColor: 'primary.main' } }}
|
||||
>
|
||||
<Cast />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={t('share')}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="inherit"
|
||||
onClick={() => {
|
||||
handleKebabMenuClose();
|
||||
handleShare();
|
||||
}}
|
||||
sx={{ minWidth: 'auto', p: 1, color: 'text.secondary', borderColor: 'text.secondary', '&:hover': { color: 'primary.main', borderColor: 'primary.main' } }}
|
||||
>
|
||||
<Share />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={t('addToCollection')}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="inherit"
|
||||
onClick={() => {
|
||||
handleKebabMenuClose();
|
||||
onAddToCollection();
|
||||
}}
|
||||
sx={{ minWidth: 'auto', p: 1, color: 'text.secondary', borderColor: 'text.secondary', '&:hover': { color: 'primary.main', borderColor: 'primary.main' } }}
|
||||
>
|
||||
<Add />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={t('delete')}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="inherit"
|
||||
onClick={() => {
|
||||
handleKebabMenuClose();
|
||||
onDelete();
|
||||
}}
|
||||
disabled={isDeleting}
|
||||
sx={{ minWidth: 'auto', p: 1, color: 'text.secondary', borderColor: 'text.secondary', '&:hover': { color: 'error.main', borderColor: 'error.main' } }}
|
||||
>
|
||||
<Delete />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</Menu>
|
||||
<VideoKebabMenuButtons
|
||||
onPlayWith={(anchor) => setPlayerMenuAnchor(anchor)}
|
||||
onShare={handleShare}
|
||||
onAddToCollection={onAddToCollection}
|
||||
onDelete={onDelete}
|
||||
isDeleting={isDeleting}
|
||||
/>
|
||||
<Menu
|
||||
anchorEl={playerMenuAnchor}
|
||||
open={Boolean(playerMenuAnchor)}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
import { Add, Cast, Delete, MoreVert, Share } from '@mui/icons-material';
|
||||
import { Button, IconButton, Menu, Stack, Tooltip } from '@mui/material';
|
||||
import React, { useState } from 'react';
|
||||
import { useLanguage } from '../../../contexts/LanguageContext';
|
||||
|
||||
interface VideoKebabMenuButtonsProps {
|
||||
onPlayWith: (anchor: HTMLElement) => void;
|
||||
onShare: () => void;
|
||||
onAddToCollection: () => void;
|
||||
onDelete: () => void;
|
||||
isDeleting?: boolean;
|
||||
}
|
||||
|
||||
const VideoKebabMenuButtons: React.FC<VideoKebabMenuButtonsProps> = ({
|
||||
onPlayWith,
|
||||
onShare,
|
||||
onAddToCollection,
|
||||
onDelete,
|
||||
isDeleting = false
|
||||
}) => {
|
||||
const { t } = useLanguage();
|
||||
const [kebabMenuAnchor, setKebabMenuAnchor] = useState<null | HTMLElement>(null);
|
||||
|
||||
const handleKebabMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setKebabMenuAnchor(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleKebabMenuClose = () => {
|
||||
setKebabMenuAnchor(null);
|
||||
};
|
||||
|
||||
const handlePlayWith = () => {
|
||||
const anchor = kebabMenuAnchor;
|
||||
handleKebabMenuClose();
|
||||
if (anchor) {
|
||||
// Pass the anchor element to the parent so it can open the player menu at the same position
|
||||
onPlayWith(anchor);
|
||||
}
|
||||
};
|
||||
|
||||
const handleShare = () => {
|
||||
handleKebabMenuClose();
|
||||
onShare();
|
||||
};
|
||||
|
||||
const handleAddToCollection = () => {
|
||||
handleKebabMenuClose();
|
||||
onAddToCollection();
|
||||
};
|
||||
|
||||
const handleDelete = () => {
|
||||
handleKebabMenuClose();
|
||||
onDelete();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="More actions">
|
||||
<IconButton
|
||||
onClick={handleKebabMenuOpen}
|
||||
sx={{
|
||||
color: kebabMenuAnchor ? 'primary.main' : 'text.secondary',
|
||||
'&:hover': { color: 'primary.main' }
|
||||
}}
|
||||
>
|
||||
<MoreVert />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Menu
|
||||
anchorEl={kebabMenuAnchor}
|
||||
open={Boolean(kebabMenuAnchor)}
|
||||
onClose={handleKebabMenuClose}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'right',
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'right',
|
||||
}}
|
||||
slotProps={{
|
||||
paper: {
|
||||
sx: {
|
||||
minWidth: 'auto',
|
||||
p: 1,
|
||||
px: 2,
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Stack direction="row" spacing={2} sx={{ justifyContent: 'flex-end' }}>
|
||||
<Tooltip title={t('playWith')}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="inherit"
|
||||
onClick={handlePlayWith}
|
||||
sx={{ minWidth: 'auto', p: 1, color: 'text.secondary', borderColor: 'text.secondary', '&:hover': { color: 'primary.main', borderColor: 'primary.main' } }}
|
||||
>
|
||||
<Cast />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={t('share')}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="inherit"
|
||||
onClick={handleShare}
|
||||
sx={{ minWidth: 'auto', p: 1, color: 'text.secondary', borderColor: 'text.secondary', '&:hover': { color: 'primary.main', borderColor: 'primary.main' } }}
|
||||
>
|
||||
<Share />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={t('addToCollection')}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="inherit"
|
||||
onClick={handleAddToCollection}
|
||||
sx={{ minWidth: 'auto', p: 1, color: 'text.secondary', borderColor: 'text.secondary', '&:hover': { color: 'primary.main', borderColor: 'primary.main' } }}
|
||||
>
|
||||
<Add />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={t('delete')}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="inherit"
|
||||
onClick={handleDelete}
|
||||
disabled={isDeleting}
|
||||
sx={{ minWidth: 'auto', p: 1, color: 'text.secondary', borderColor: 'text.secondary', '&:hover': { color: 'error.main', borderColor: 'error.main' } }}
|
||||
>
|
||||
<Delete />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</Menu>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoKebabMenuButtons;
|
||||
|
||||
Reference in New Issue
Block a user