mirror of
https://git.unlock-music.dev/um/um-react.git
synced 2024-11-27 19:42:15 +00:00
feat: 歌曲封面使用 Image 组件,删除歌曲行数据时使用一个动画效果来过渡一下
This commit is contained in:
parent
e60e669d32
commit
8a825affd0
@ -1,20 +1,22 @@
|
|||||||
import {
|
import {
|
||||||
Avatar,
|
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
CardBody,
|
CardBody,
|
||||||
Center,
|
Center,
|
||||||
|
Collapse,
|
||||||
Grid,
|
Grid,
|
||||||
GridItem,
|
GridItem,
|
||||||
|
Image,
|
||||||
Link,
|
Link,
|
||||||
Text,
|
Text,
|
||||||
|
useDisclosure,
|
||||||
VStack,
|
VStack,
|
||||||
Wrap,
|
Wrap,
|
||||||
WrapItem,
|
WrapItem,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { DecryptedAudioFile, ProcessState, deleteFile } from './fileListingSlice';
|
import { DecryptedAudioFile, deleteFile, ProcessState } from './fileListingSlice';
|
||||||
import { useRef } from 'react';
|
import { useCallback, useRef } from 'react';
|
||||||
import { useAppDispatch } from '~/hooks';
|
import { useAppDispatch } from '~/hooks';
|
||||||
|
|
||||||
interface FileRowProps {
|
interface FileRowProps {
|
||||||
@ -23,6 +25,7 @@ interface FileRowProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function FileRow({ id, file }: FileRowProps) {
|
export function FileRow({ id, file }: FileRowProps) {
|
||||||
|
const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: true });
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const isDecrypted = file.state === ProcessState.COMPLETE;
|
const isDecrypted = file.state === ProcessState.COMPLETE;
|
||||||
|
|
||||||
@ -30,7 +33,7 @@ export function FileRow({ id, file }: FileRowProps) {
|
|||||||
const decryptedName = nameWithoutExt + '.' + file.ext;
|
const decryptedName = nameWithoutExt + '.' + file.ext;
|
||||||
|
|
||||||
const audioPlayerRef = useRef<HTMLAudioElement>(null);
|
const audioPlayerRef = useRef<HTMLAudioElement>(null);
|
||||||
const togglePlay = () => {
|
const togglePlay = useCallback(() => {
|
||||||
const player = audioPlayerRef.current;
|
const player = audioPlayerRef.current;
|
||||||
if (!player) {
|
if (!player) {
|
||||||
return;
|
return;
|
||||||
@ -41,87 +44,97 @@ export function FileRow({ id, file }: FileRowProps) {
|
|||||||
} else {
|
} else {
|
||||||
player.pause();
|
player.pause();
|
||||||
}
|
}
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
const handleDeleteRow = () => {
|
const handleDeleteRow = useCallback(() => {
|
||||||
dispatch(deleteFile({ id }));
|
onToggle();
|
||||||
};
|
setTimeout(() => {
|
||||||
|
dispatch(deleteFile({ id }));
|
||||||
|
}, 500);
|
||||||
|
}, [dispatch, id, onToggle]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card w="full">
|
<Collapse in={isOpen} animateOpacity unmountOnExit startingHeight={0} style={{ width: '100%' }}>
|
||||||
<CardBody>
|
<Card w="full">
|
||||||
<Grid
|
<CardBody>
|
||||||
templateAreas={{
|
<Grid
|
||||||
base: `
|
templateAreas={{
|
||||||
|
base: `
|
||||||
"cover"
|
"cover"
|
||||||
"title"
|
"title"
|
||||||
"meta"
|
"meta"
|
||||||
"action"
|
"action"
|
||||||
`,
|
`,
|
||||||
md: `
|
md: `
|
||||||
"cover title title"
|
"cover title title"
|
||||||
"cover meta action"
|
"cover meta action"
|
||||||
`,
|
`,
|
||||||
}}
|
}}
|
||||||
gridTemplateRows={{
|
gridTemplateRows={{
|
||||||
base: 'repeat(auto-fill)',
|
base: 'repeat(auto-fill)',
|
||||||
md: 'min-content 1fr',
|
md: 'min-content 1fr',
|
||||||
}}
|
}}
|
||||||
gridTemplateColumns={{
|
gridTemplateColumns={{
|
||||||
base: '1fr',
|
base: '1fr',
|
||||||
md: '160px 1fr',
|
md: '160px 1fr',
|
||||||
}}
|
}}
|
||||||
gap="1"
|
gap="1"
|
||||||
>
|
>
|
||||||
<GridItem area="cover">
|
<GridItem area="cover">
|
||||||
<Center w="160px" h="160px" m="auto">
|
<Center w="160px" h="160px" m="auto">
|
||||||
{file.metadata.cover && <Avatar size="sm" name="专辑封面" src={file.metadata.cover} />}
|
<Image
|
||||||
{!file.metadata.cover && <Text>暂无封面</Text>}
|
boxSize='160px'
|
||||||
</Center>
|
objectFit='cover'
|
||||||
</GridItem>
|
src={file.metadata.cover}
|
||||||
<GridItem area="title">
|
alt={file.metadata.album}
|
||||||
<Box w="full" as="h4" fontWeight="semibold" mt="1" textAlign={{ base: 'center', md: 'left' }}>
|
fallbackSrc='https://via.placeholder.com/160'
|
||||||
{file.metadata.name || nameWithoutExt}
|
/>
|
||||||
</Box>
|
</Center>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
<GridItem area="meta">
|
<GridItem area="title">
|
||||||
{isDecrypted && (
|
<Box w="full" as="h4" fontWeight="semibold" mt="1" textAlign={{ base: 'center', md: 'left' }}>
|
||||||
<Box>
|
{file.metadata.name || nameWithoutExt}
|
||||||
<Text>专辑: {file.metadata.album}</Text>
|
|
||||||
<Text>艺术家: {file.metadata.artist}</Text>
|
|
||||||
<Text>专辑艺术家: {file.metadata.albumArtist}</Text>
|
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
</GridItem>
|
||||||
</GridItem>
|
<GridItem area="meta">
|
||||||
<GridItem area="action">
|
{isDecrypted && (
|
||||||
<VStack>
|
<Box>
|
||||||
{file.decrypted && <audio controls autoPlay={false} src={file.decrypted} ref={audioPlayerRef} />}
|
<Text>专辑: {file.metadata.album}</Text>
|
||||||
|
<Text>艺术家: {file.metadata.artist}</Text>
|
||||||
|
<Text>专辑艺术家: {file.metadata.albumArtist}</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</GridItem>
|
||||||
|
<GridItem area="action">
|
||||||
|
<VStack>
|
||||||
|
{file.decrypted && <audio controls autoPlay={false} src={file.decrypted} ref={audioPlayerRef} />}
|
||||||
|
|
||||||
<Wrap>
|
<Wrap>
|
||||||
{isDecrypted && (
|
{isDecrypted && (
|
||||||
|
<WrapItem>
|
||||||
|
<Button type="button" onClick={togglePlay}>
|
||||||
|
播放/暂停
|
||||||
|
</Button>
|
||||||
|
</WrapItem>
|
||||||
|
)}
|
||||||
<WrapItem>
|
<WrapItem>
|
||||||
<Button type="button" onClick={togglePlay}>
|
{file.decrypted && (
|
||||||
播放/暂停
|
<Link isExternal href={file.decrypted} download={decryptedName}>
|
||||||
|
<Button as="span">下载</Button>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</WrapItem>
|
||||||
|
<WrapItem>
|
||||||
|
<Button type="button" onClick={handleDeleteRow}>
|
||||||
|
删除
|
||||||
</Button>
|
</Button>
|
||||||
</WrapItem>
|
</WrapItem>
|
||||||
)}
|
</Wrap>
|
||||||
<WrapItem>
|
</VStack>
|
||||||
{file.decrypted && (
|
</GridItem>
|
||||||
<Link isExternal href={file.decrypted} download={decryptedName}>
|
</Grid>
|
||||||
<Button as="span">下载</Button>
|
</CardBody>
|
||||||
</Link>
|
</Card>
|
||||||
)}
|
</Collapse>
|
||||||
</WrapItem>
|
|
||||||
<WrapItem>
|
|
||||||
<Button type="button" onClick={handleDeleteRow}>
|
|
||||||
删除
|
|
||||||
</Button>
|
|
||||||
</WrapItem>
|
|
||||||
</Wrap>
|
|
||||||
</VStack>
|
|
||||||
</GridItem>
|
|
||||||
</Grid>
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user