132 lines
4.3 KiB
TypeScript
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: ``,
|
|
});
|
|
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>
|
|
);
|
|
};
|