// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import React, {useCallback, useMemo} from 'react'; import {StyleSheet, View} from 'react-native'; import SyntaxHighlighter from 'react-syntax-highlighter'; import {githubGist as github, monokai, solarizedDark, solarizedLight} from 'react-syntax-highlighter/dist/cjs/styles/hljs'; import {useTheme} from '@context/theme'; import CodeHighlightRenderer from './renderer'; import type {SyntaxHiglightProps} from '@typings/components/syntax_highlight'; const codeTheme: Record = { github, monokai, 'solarized-dark': solarizedDark, 'solarized-light': solarizedLight, }; const styles = StyleSheet.create({ preTag: { padding: 5, width: '100%', }, flex: { flex: 1, }, }); function getMaximumLineLength(code: string) { return code.split('\n').reduce((prev, v) => Math.max(prev, v.length), 0); } const MAXIMUM_CODE_LINE_LENGTH = 300; const Highlighter = ({code, language, textStyle, selectable = false}: SyntaxHiglightProps) => { const theme = useTheme(); const style = codeTheme[theme.codeTheme] || github; const preTagStyle = useMemo(() => [ styles.preTag, selectable && styles.flex, {backgroundColor: style.hljs.background || theme.centerChannelBg}, ], [theme, selectable, style]); const maximumLineLength = useMemo(() => getMaximumLineLength(code), [code]); const languageToUse = maximumLineLength > MAXIMUM_CODE_LINE_LENGTH ? 'text' : language; const nativeRenderer = useCallback(({rows, stylesheet}: rendererProps) => { const digits = rows.length.toString().length; return ( ); }, [style.hljs.color, theme.centerChannelColor, textStyle, selectable]); const preTag = useCallback((info: any) => ( {info.children} ), [preTagStyle]); return ( {code} ); }; export default Highlighter;