### What problem does this PR solve? Add document viewers for text and markdown files ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.20.0
| @@ -2,6 +2,8 @@ import { Images } from '@/constants/common'; | |||
| import { api_host } from '@/utils/api'; | |||
| import { Flex } from 'antd'; | |||
| import { useParams, useSearchParams } from 'umi'; | |||
| import Md from './md'; | |||
| import Text from './text'; | |||
| import Docx from './docx'; | |||
| import Excel from './excel'; | |||
| import Image from './image'; | |||
| @@ -31,6 +33,9 @@ const DocumentViewer = () => { | |||
| <Image src={api} preview={false}></Image> | |||
| </Flex> | |||
| )} | |||
| {ext === 'md' && <Md filePath={api}></Md>} | |||
| {ext === 'txt' && <Text filePath={api}></Text>} | |||
| {ext === 'pdf' && <Pdf url={api}></Pdf>} | |||
| {(ext === 'xlsx' || ext === 'xls') && <Excel filePath={api}></Excel>} | |||
| @@ -0,0 +1,34 @@ | |||
| import React, { useEffect, useState } from 'react'; | |||
| import ReactMarkdown from 'react-markdown'; | |||
| import remarkGfm from 'remark-gfm'; | |||
| import FileError from '../file-error'; | |||
| interface MdProps { | |||
| filePath: string; | |||
| } | |||
| const Md: React.FC<MdProps> = ({ filePath }) => { | |||
| const [content, setContent] = useState<string>(''); | |||
| const [error, setError] = useState<string | null>(null); | |||
| useEffect(() => { | |||
| setError(null); | |||
| fetch(filePath) | |||
| .then((res) => { | |||
| if (!res.ok) throw new Error('Failed to fetch markdown file'); | |||
| return res.text(); | |||
| }) | |||
| .then((text) => setContent(text)) | |||
| .catch((err) => setError(err.message)) | |||
| }, [filePath]); | |||
| if (error) return (<FileError>{error}</FileError>); | |||
| return ( | |||
| <div style={{ padding: 24, height: "100vh", overflow: "scroll" }}> | |||
| <ReactMarkdown remarkPlugins={[remarkGfm]}>{content}</ReactMarkdown> | |||
| </div> | |||
| ); | |||
| }; | |||
| export default Md; | |||
| @@ -0,0 +1,32 @@ | |||
| import React, { useEffect, useState } from 'react'; | |||
| import FileError from '../file-error'; | |||
| interface TxtProps { | |||
| filePath: string; | |||
| } | |||
| const Md: React.FC<TxtProps> = ({ filePath }) => { | |||
| const [content, setContent] = useState<string>(''); | |||
| const [error, setError] = useState<string | null>(null); | |||
| useEffect(() => { | |||
| setError(null); | |||
| fetch(filePath) | |||
| .then((res) => { | |||
| if (!res.ok) throw new Error('Failed to fetch text file'); | |||
| return res.text(); | |||
| }) | |||
| .then((text) => setContent(text)) | |||
| .catch((err) => setError(err.message)) | |||
| }, [filePath]); | |||
| if (error) return (<FileError>{error}</FileError>); | |||
| return ( | |||
| <div style={{ padding: 24, height: "100vh", overflow: "scroll" }}> | |||
| {content} | |||
| </div> | |||
| ); | |||
| }; | |||
| export default Md; | |||