59 lines
1.6 KiB
TypeScript
59 lines
1.6 KiB
TypeScript
import type { FC } from '../../../lib/teact/teact';
|
|
import React, { memo, useCallback, useState } from '../../../lib/teact/teact';
|
|
|
|
import { ApiMessageEntityTypes } from '../../../api/types';
|
|
|
|
import buildClassName from '../../../util/buildClassName';
|
|
import { getPrettyCodeLanguageName } from '../../../util/prettyCodeLanguageNames';
|
|
|
|
import useAsync from '../../../hooks/useAsync';
|
|
|
|
import PeerColorWrapper from '../PeerColorWrapper';
|
|
import CodeOverlay from './CodeOverlay';
|
|
|
|
import './CodeBlock.scss';
|
|
|
|
export type OwnProps = {
|
|
text: string;
|
|
language?: string;
|
|
noCopy?: boolean;
|
|
};
|
|
|
|
const CodeBlock: FC<OwnProps> = ({ text, language, noCopy }) => {
|
|
const [isWordWrap, setWordWrap] = useState(true);
|
|
|
|
const { result: highlighted } = useAsync(() => {
|
|
if (!language) return Promise.resolve(undefined);
|
|
return import('../../../util/highlightCode')
|
|
.then((lib) => lib.default(text, language));
|
|
}, [language, text]);
|
|
|
|
const handleWordWrapToggle = useCallback((wrap) => {
|
|
setWordWrap(wrap);
|
|
}, []);
|
|
|
|
const blockClass = buildClassName(
|
|
'code-block',
|
|
!isWordWrap && 'no-word-wrap',
|
|
);
|
|
|
|
return (
|
|
<PeerColorWrapper
|
|
className="CodeBlock"
|
|
>
|
|
{language && (<p className="code-title">{getPrettyCodeLanguageName(language)}</p>)}
|
|
<pre className={blockClass} data-entity-type={ApiMessageEntityTypes.Pre} data-language={language}>
|
|
{highlighted ?? text}
|
|
<CodeOverlay
|
|
text={text}
|
|
className="code-overlay"
|
|
onWordWrapToggle={handleWordWrapToggle}
|
|
noCopy={noCopy}
|
|
/>
|
|
</pre>
|
|
</PeerColorWrapper>
|
|
);
|
|
};
|
|
|
|
export default memo(CodeBlock);
|