Render file as readable with ext (#1446)
This commit is contained in:
parent
609b132106
commit
152576e85d
4 changed files with 58 additions and 11 deletions
|
@ -4,7 +4,6 @@ import classNames from 'classnames';
|
||||||
import { Box, Chip, Header, Icon, IconButton, Icons, Scroll, Text, as } from 'folds';
|
import { Box, Chip, Header, Icon, IconButton, Icons, Scroll, Text, as } from 'folds';
|
||||||
import { ErrorBoundary } from 'react-error-boundary';
|
import { ErrorBoundary } from 'react-error-boundary';
|
||||||
import * as css from './TextViewer.css';
|
import * as css from './TextViewer.css';
|
||||||
import { mimeTypeToExt } from '../../utils/mimeTypes';
|
|
||||||
import { copyToClipboard } from '../../utils/dom';
|
import { copyToClipboard } from '../../utils/dom';
|
||||||
|
|
||||||
const ReactPrism = lazy(() => import('../../plugins/react-prism/ReactPrism'));
|
const ReactPrism = lazy(() => import('../../plugins/react-prism/ReactPrism'));
|
||||||
|
@ -12,12 +11,12 @@ const ReactPrism = lazy(() => import('../../plugins/react-prism/ReactPrism'));
|
||||||
export type TextViewerProps = {
|
export type TextViewerProps = {
|
||||||
name: string;
|
name: string;
|
||||||
text: string;
|
text: string;
|
||||||
mimeType: string;
|
langName: string;
|
||||||
requestClose: () => void;
|
requestClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TextViewer = as<'div', TextViewerProps>(
|
export const TextViewer = as<'div', TextViewerProps>(
|
||||||
({ className, name, text, mimeType, requestClose, ...props }, ref) => {
|
({ className, name, text, langName, requestClose, ...props }, ref) => {
|
||||||
const handleCopy = () => {
|
const handleCopy = () => {
|
||||||
copyToClipboard(text);
|
copyToClipboard(text);
|
||||||
};
|
};
|
||||||
|
@ -51,10 +50,7 @@ export const TextViewer = as<'div', TextViewerProps>(
|
||||||
alignItems="Center"
|
alignItems="Center"
|
||||||
>
|
>
|
||||||
<Scroll hideTrack variant="Background" visibility="Hover">
|
<Scroll hideTrack variant="Background" visibility="Hover">
|
||||||
<Text
|
<Text as="pre" className={classNames(css.TextViewerPre, `language-${langName}`)}>
|
||||||
as="pre"
|
|
||||||
className={classNames(css.TextViewerPre, `language-${mimeTypeToExt(mimeType)}`)}
|
|
||||||
>
|
|
||||||
<ErrorBoundary fallback={<code>{text}</code>}>
|
<ErrorBoundary fallback={<code>{text}</code>}>
|
||||||
<Suspense fallback={<code>{text}</code>}>
|
<Suspense fallback={<code>{text}</code>}>
|
||||||
<ReactPrism>{(codeRef) => <code ref={codeRef}>{text}</code>}</ReactPrism>
|
<ReactPrism>{(codeRef) => <code ref={codeRef}>{text}</code>}</ReactPrism>
|
||||||
|
|
|
@ -23,7 +23,12 @@ import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||||
import { getFileSrcUrl, getSrcFile } from './util';
|
import { getFileSrcUrl, getSrcFile } from './util';
|
||||||
import { bytesToSize } from '../../../utils/common';
|
import { bytesToSize } from '../../../utils/common';
|
||||||
import { TextViewer } from '../../../components/text-viewer';
|
import { TextViewer } from '../../../components/text-viewer';
|
||||||
import { READABLE_TEXT_MIME_TYPES } from '../../../utils/mimeTypes';
|
import {
|
||||||
|
READABLE_EXT_TO_MIME_TYPE,
|
||||||
|
READABLE_TEXT_MIME_TYPES,
|
||||||
|
getFileNameExt,
|
||||||
|
mimeTypeToExt,
|
||||||
|
} from '../../../utils/mimeTypes';
|
||||||
import { PdfViewer } from '../../../components/Pdf-viewer';
|
import { PdfViewer } from '../../../components/Pdf-viewer';
|
||||||
import * as css from './styles.css';
|
import * as css from './styles.css';
|
||||||
|
|
||||||
|
@ -103,7 +108,11 @@ function ReadTextFile({ body, mimeType, url, encInfo }: Omit<FileContentProps, '
|
||||||
<TextViewer
|
<TextViewer
|
||||||
name={body}
|
name={body}
|
||||||
text={textState.data}
|
text={textState.data}
|
||||||
mimeType={mimeType}
|
langName={
|
||||||
|
READABLE_TEXT_MIME_TYPES.includes(mimeType)
|
||||||
|
? mimeTypeToExt(mimeType)
|
||||||
|
: mimeTypeToExt(READABLE_EXT_TO_MIME_TYPE[getFileNameExt(body)] ?? mimeType)
|
||||||
|
}
|
||||||
requestClose={() => setTextViewer(false)}
|
requestClose={() => setTextViewer(false)}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -247,7 +256,8 @@ function DownloadFile({ body, mimeType, url, info, encInfo }: FileContentProps)
|
||||||
export const FileContent = as<'div', FileContentProps>(
|
export const FileContent = as<'div', FileContentProps>(
|
||||||
({ body, mimeType, url, info, encInfo, ...props }, ref) => (
|
({ body, mimeType, url, info, encInfo, ...props }, ref) => (
|
||||||
<Box direction="Column" gap="300" {...props} ref={ref}>
|
<Box direction="Column" gap="300" {...props} ref={ref}>
|
||||||
{READABLE_TEXT_MIME_TYPES.includes(mimeType) && (
|
{(READABLE_TEXT_MIME_TYPES.includes(mimeType) ||
|
||||||
|
READABLE_EXT_TO_MIME_TYPE[getFileNameExt(body)]) && (
|
||||||
<ReadTextFile body={body} mimeType={mimeType} url={url} encInfo={encInfo} />
|
<ReadTextFile body={body} mimeType={mimeType} url={url} encInfo={encInfo} />
|
||||||
)}
|
)}
|
||||||
{mimeType === 'application/pdf' && (
|
{mimeType === 'application/pdf' && (
|
||||||
|
|
|
@ -246,7 +246,7 @@ export const MessageSourceCodeItem = as<
|
||||||
<Modal variant="Surface" size="500">
|
<Modal variant="Surface" size="500">
|
||||||
<TextViewer
|
<TextViewer
|
||||||
name="Source Code"
|
name="Source Code"
|
||||||
mimeType="application/json"
|
langName="json"
|
||||||
text={text}
|
text={text}
|
||||||
requestClose={handleClose}
|
requestClose={handleClose}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -57,6 +57,43 @@ export const READABLE_TEXT_MIME_TYPES = [
|
||||||
...TEXT_MIME_TYPE,
|
...TEXT_MIME_TYPE,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const READABLE_EXT_TO_MIME_TYPE: Record<string, string> = {
|
||||||
|
go: 'text/go',
|
||||||
|
rs: 'text/rust',
|
||||||
|
py: 'text/python',
|
||||||
|
swift: 'text/swift',
|
||||||
|
c: 'text/c',
|
||||||
|
cpp: 'text/cpp',
|
||||||
|
java: 'text/java',
|
||||||
|
kt: 'text/kotlin',
|
||||||
|
lua: 'text/lua',
|
||||||
|
php: 'text/php',
|
||||||
|
ts: 'text/typescript',
|
||||||
|
js: 'text/javascript',
|
||||||
|
jsx: 'text/jsx',
|
||||||
|
tsx: 'text/tsx',
|
||||||
|
html: 'text/html',
|
||||||
|
xhtml: 'text/xhtml',
|
||||||
|
xht: 'text/xhtml',
|
||||||
|
css: 'text/css',
|
||||||
|
scss: 'text/scss',
|
||||||
|
sass: 'text/sass',
|
||||||
|
json: 'text/json',
|
||||||
|
md: 'text/markdown',
|
||||||
|
yaml: 'text/yaml',
|
||||||
|
yni: 'text/yni',
|
||||||
|
xml: 'text/xml',
|
||||||
|
txt: 'text/plain',
|
||||||
|
text: 'text/plain',
|
||||||
|
conf: 'text/conf',
|
||||||
|
cfg: 'text/conf',
|
||||||
|
cnf: 'text/conf',
|
||||||
|
log: 'text/log',
|
||||||
|
me: 'text/me',
|
||||||
|
cvs: 'text/cvs',
|
||||||
|
tvs: 'text/tvs',
|
||||||
|
};
|
||||||
|
|
||||||
export const ALLOWED_BLOB_MIME_TYPES = [
|
export const ALLOWED_BLOB_MIME_TYPES = [
|
||||||
...IMAGE_MIME_TYPES,
|
...IMAGE_MIME_TYPES,
|
||||||
...VIDEO_MIME_TYPES,
|
...VIDEO_MIME_TYPES,
|
||||||
|
@ -92,3 +129,7 @@ export const mimeTypeToExt = (mimeType: string): string => {
|
||||||
const extStart = mimeType.lastIndexOf('/') + 1;
|
const extStart = mimeType.lastIndexOf('/') + 1;
|
||||||
return mimeType.slice(extStart);
|
return mimeType.slice(extStart);
|
||||||
};
|
};
|
||||||
|
export const getFileNameExt = (fileName: string): string => {
|
||||||
|
const extStart = fileName.lastIndexOf('.') + 1;
|
||||||
|
return fileName.slice(extStart);
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue