2025-03-18 16:14:40 +08:00

132 lines
4.3 KiB
TypeScript

import { useResourceFileStore } from '@kevisual/resources/pages/store/resource-file';
import { useSettingsStore } from '@kevisual/resources/pages/store/settings';
import { Button, Tooltip, useTheme } from '@mui/material';
import { useShallow } from 'zustand/shallow';
import { Accordion, AccordionSummary, AccordionDetails } from '@mui/material';
import { ChevronDown } from 'lucide-react';
import { useMemo } from 'react';
import { getFileType } from '../../FileIcon';
import { toast } from 'react-toastify';
import clsx from 'clsx';
type AccordionItem = {
title?: string;
key?: string;
url?: string;
content?: any;
clickCopy?: boolean;
};
export const QuickPreview = () => {
const { resource } = useResourceFileStore(
useShallow((state) => ({
resource: state.resource,
})),
);
const { settings, baseUrl } = useSettingsStore(
useShallow((state) => ({
settings: state.settings,
baseUrl: state.baseUrl,
})),
);
const fileType = useMemo(() => getFileType(resource?.name), [resource]);
const accordionList = useMemo(() => {
const username = settings?.username;
if (!username) {
toast.error('请先登录');
return [];
}
const _url = new URL(`${baseUrl}/api/s1/share/${username}/${resource?.name}`);
const meta = resource?.metaData ?? {};
if (meta.password) {
_url.searchParams.set('p', meta.password);
}
const url = _url.toString();
let accordionList: AccordionItem[] = [];
const encodeUrl = encodeURIComponent(url);
const previewUrl = `${baseUrl}/app/preview?fileUrl=${encodeUrl}&fileType=${fileType}`;
accordionList.push({
title: '文件预览',
key: 'preview-file',
url: previewUrl,
content: (
<div className=''>
<div className='text-sm break-words'>{previewUrl}</div>
<Button variant='contained' color='primary' style={{ color: 'white' }} onClick={() => window.open(previewUrl, '_blank')}>
</Button>
</div>
),
});
if (fileType === 'image') {
accordionList.push({
title: '预览图片',
key: 'preview-image',
url: url,
content: <img className='w-full h-full border-2 border-gray-300 rounded-md' src={url} alt={resource?.name} />,
});
accordionList.push({
title: 'markdown链接',
key: 'markdown-link',
url: url,
clickCopy: true,
content: `![${resource?.name}](${url})`,
});
accordionList.push({
title: 'HTML图片',
key: 'html-image',
url: url,
clickCopy: true,
content: `<img style="width: 100%;height: 100%;" src="${url}" alt="${resource?.name}" />`,
});
accordionList.push({
title: 'HTML超链接',
key: 'html-link',
url: url,
clickCopy: true,
content: `<a href="${url}">${resource?.name}</a>`,
});
}
const downloadUrl = new URL(url);
downloadUrl.searchParams.set('download', 'true');
accordionList.push({
title: '下载地址',
key: 'download-url',
url: downloadUrl.toString(),
content: (
<div className=''>
<div className='text-sm break-words'>{downloadUrl.toString()}</div>
<Button variant='contained' color='primary' style={{ color: 'white' }} onClick={() => window.open(downloadUrl.toString(), '_blank')}>
</Button>
</div>
),
});
return accordionList;
}, [resource, baseUrl, settings]);
const theme = useTheme();
return (
<div className='p-4'>
{accordionList.map((item) => (
<Accordion key={item.key}>
<AccordionSummary expandIcon={<ChevronDown color={theme.palette.text.secondary} />}>{item.title}</AccordionSummary>
<AccordionDetails>
<div
className={clsx('text-sm whitespace-pre-wrap w-full overflow-ellipsis overflow-hidden', {
'cursor-copy': item.clickCopy, // cursor-copy的有吗
})}
onClick={() => {
if (item.clickCopy) {
navigator.clipboard.writeText(item.content);
toast.success('复制成功');
}
}}>
{item.content}
</div>
</AccordionDetails>
</Accordion>
))}
</div>
);
};