Merge remote-tracking branch 'houkunlin/feat/file-row' into merge-houkunlin
This commit is contained in:
commit
c0bc9858d0
@ -4,19 +4,21 @@ import {
|
||||
Card,
|
||||
CardBody,
|
||||
Center,
|
||||
Collapse,
|
||||
Grid,
|
||||
GridItem,
|
||||
Image,
|
||||
Link,
|
||||
Text,
|
||||
useDisclosure,
|
||||
VStack,
|
||||
Wrap,
|
||||
WrapItem,
|
||||
} from '@chakra-ui/react';
|
||||
import { DecryptedAudioFile, ProcessState, deleteFile } from './fileListingSlice';
|
||||
import { useRef } from 'react';
|
||||
import { DecryptedAudioFile, deleteFile, ProcessState } from './fileListingSlice';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { useAppDispatch } from '~/hooks';
|
||||
import coverFallback from '~/assets/no-cover.svg';
|
||||
import coverSvgUrl from '~/assets/no-cover.svg';
|
||||
|
||||
interface FileRowProps {
|
||||
id: string;
|
||||
@ -24,6 +26,7 @@ interface FileRowProps {
|
||||
}
|
||||
|
||||
export function FileRow({ id, file }: FileRowProps) {
|
||||
const { isOpen, onClose } = useDisclosure({ defaultIsOpen: true });
|
||||
const dispatch = useAppDispatch();
|
||||
const isDecrypted = file.state === ProcessState.COMPLETE;
|
||||
const metadata = file.metadata;
|
||||
@ -45,97 +48,100 @@ export function FileRow({ id, file }: FileRowProps) {
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteRow = () => {
|
||||
dispatch(deleteFile({ id }));
|
||||
};
|
||||
const handleDeleteRow = useCallback(() => {
|
||||
onClose();
|
||||
setTimeout(() => {
|
||||
dispatch(deleteFile({ id }));
|
||||
}, 500);
|
||||
}, [dispatch, id, onClose]);
|
||||
|
||||
return (
|
||||
<Card w="full" data-testid="file-row">
|
||||
<CardBody>
|
||||
<Grid
|
||||
templateAreas={{
|
||||
base: `
|
||||
<Collapse in={isOpen} animateOpacity unmountOnExit startingHeight={0} style={{ width: '100%' }}>
|
||||
<Card w="full" data-testid="file-row">
|
||||
<CardBody>
|
||||
<Grid
|
||||
templateAreas={{
|
||||
base: `
|
||||
"cover"
|
||||
"title"
|
||||
"meta"
|
||||
"action"
|
||||
`,
|
||||
md: `
|
||||
md: `
|
||||
"cover title title"
|
||||
"cover meta action"
|
||||
`,
|
||||
}}
|
||||
gridTemplateRows={{
|
||||
base: 'repeat(auto-fill)',
|
||||
md: 'min-content 1fr',
|
||||
}}
|
||||
gridTemplateColumns={{
|
||||
base: '1fr',
|
||||
md: '160px 1fr',
|
||||
}}
|
||||
gap="1"
|
||||
>
|
||||
<GridItem area="cover">
|
||||
<Center w="160px" h="160px" m="auto">
|
||||
{metadata && (
|
||||
}}
|
||||
gridTemplateRows={{
|
||||
base: 'repeat(auto-fill)',
|
||||
md: 'min-content 1fr',
|
||||
}}
|
||||
gridTemplateColumns={{
|
||||
base: '1fr',
|
||||
md: '160px 1fr',
|
||||
}}
|
||||
gap="1"
|
||||
>
|
||||
<GridItem area="cover">
|
||||
<Center w="160px" h="160px" m="auto">
|
||||
<Image
|
||||
objectFit="cover"
|
||||
src={metadata.cover}
|
||||
alt={`"${metadata.album}" 的专辑封面`}
|
||||
fallbackSrc={coverFallback}
|
||||
src={metadata?.cover}
|
||||
alt={`${metadata?.album} 的专辑封面`}
|
||||
fallbackSrc={coverSvgUrl}
|
||||
/>
|
||||
)}
|
||||
</Center>
|
||||
</GridItem>
|
||||
<GridItem area="title">
|
||||
<Box w="full" as="h4" fontWeight="semibold" mt="1" textAlign={{ base: 'center', md: 'left' }}>
|
||||
<span data-testid="audio-meta-song-name">{metadata?.name ?? nameWithoutExt}</span>
|
||||
</Box>
|
||||
</GridItem>
|
||||
<GridItem area="meta">
|
||||
{isDecrypted && metadata && (
|
||||
<Box>
|
||||
<Text>
|
||||
专辑: <span data-testid="audio-meta-album-name">{metadata.album}</span>
|
||||
</Text>
|
||||
<Text>
|
||||
艺术家: <span data-testid="audio-meta-song-artist">{metadata.artist}</span>
|
||||
</Text>
|
||||
<Text>
|
||||
专辑艺术家: <span data-testid="audio-meta-album-artist">{metadata.albumArtist}</span>
|
||||
</Text>
|
||||
</Center>
|
||||
</GridItem>
|
||||
<GridItem area="title">
|
||||
<Box w="full" as="h4" fontWeight="semibold" mt="1" textAlign={{ base: 'center', md: 'left' }}>
|
||||
<span data-testid="audio-meta-song-name">{metadata?.name ?? nameWithoutExt}</span>
|
||||
</Box>
|
||||
)}
|
||||
</GridItem>
|
||||
<GridItem area="action">
|
||||
<VStack>
|
||||
{file.decrypted && <audio controls autoPlay={false} src={file.decrypted} ref={audioPlayerRef} />}
|
||||
</GridItem>
|
||||
<GridItem area="meta">
|
||||
{isDecrypted && metadata && (
|
||||
<Box>
|
||||
<Text>
|
||||
专辑: <span data-testid="audio-meta-album-name">{metadata.album}</span>
|
||||
</Text>
|
||||
<Text>
|
||||
艺术家: <span data-testid="audio-meta-song-artist">{metadata.artist}</span>
|
||||
</Text>
|
||||
<Text>
|
||||
专辑艺术家: <span data-testid="audio-meta-album-artist">{metadata.albumArtist}</span>
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</GridItem>
|
||||
<GridItem area="action">
|
||||
<VStack>
|
||||
{file.decrypted && <audio controls autoPlay={false} src={file.decrypted} ref={audioPlayerRef} />}
|
||||
|
||||
<Wrap>
|
||||
{isDecrypted && (
|
||||
<Wrap>
|
||||
{isDecrypted && (
|
||||
<WrapItem>
|
||||
<Button type="button" onClick={togglePlay}>
|
||||
播放/暂停
|
||||
</Button>
|
||||
</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>
|
||||
</WrapItem>
|
||||
)}
|
||||
<WrapItem>
|
||||
{file.decrypted && (
|
||||
<Link isExternal href={file.decrypted} download={decryptedName}>
|
||||
<Button as="span">下载</Button>
|
||||
</Link>
|
||||
)}
|
||||
</WrapItem>
|
||||
<WrapItem>
|
||||
<Button type="button" onClick={handleDeleteRow}>
|
||||
删除
|
||||
</Button>
|
||||
</WrapItem>
|
||||
</Wrap>
|
||||
</VStack>
|
||||
</GridItem>
|
||||
</Grid>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Wrap>
|
||||
</VStack>
|
||||
</GridItem>
|
||||
</Grid>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Collapse>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user