// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {PropTypes} from 'prop-types';
import React from 'react';
import {Keyboard, View, Text, StyleSheet, Platform} from 'react-native';
import MathView from 'react-native-math-view';
import {goToScreen} from '@actions/navigation';
import FormattedText from '@components/formatted_text';
import TouchableWithFeedback from '@components/touchable_with_feedback';
import {splitLatexCodeInLines} from '@utils/latex';
import {getDisplayNameForLanguage} from '@utils/markdown';
import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import MarkdownCodeBlock from '../markdown_code_block/markdown_code_block';
const MAX_LINES = 2;
export default class LatexCodeBlock extends MarkdownCodeBlock {
static propTypes = {
theme: PropTypes.object.isRequired,
content: PropTypes.string.isRequired,
textStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]),
};
handlePress = preventDoubleTap(() => {
const {content} = this.props;
const {intl} = this.context;
const screen = 'Latex';
const passProps = {
content,
};
const languageDisplayName = getDisplayNameForLanguage('latex');
let title;
if (languageDisplayName) {
title = intl.formatMessage(
{
id: 'mobile.routes.code',
defaultMessage: '{language} Code',
},
{
language: languageDisplayName,
},
);
} else {
title = intl.formatMessage({
id: 'mobile.routes.code.noLanguage',
defaultMessage: 'LaTeX Code',
});
}
Keyboard.dismiss();
requestAnimationFrame(() => {
goToScreen(screen, title, passProps);
});
});
splitContent = (content) => {
const lines = splitLatexCodeInLines(content);
const numberOfLines = lines.length;
if (numberOfLines > MAX_LINES) {
return {
content: lines.slice(0, MAX_LINES),
numberOfLines,
};
}
return {
content: lines,
numberOfLines,
};
};
onErrorMessage = (errorMsg) => {
const style = getStyleSheet(this.props.theme);
return {'Error: ' + errorMsg.message};
};
onRenderErrorMessage = (errorMsg) => {
const style = getStyleSheet(this.props.theme);
return {'Render error: ' + errorMsg.error.message};
};
render() {
const style = getStyleSheet(this.props.theme);
let language = null;
const languageDisplayName = getDisplayNameForLanguage('latex');
if (languageDisplayName) {
language = (
{languageDisplayName}
);
}
const {content, numberOfLines} = this.splitContent(this.props.content);
let plusMoreLines = null;
if (numberOfLines > MAX_LINES) {
plusMoreLines = (
);
}
/**
* Note on the error behavior of math view:
* - onError returns an Error object
* - renderError returns an options object with an error attribute that contains the real Error.
*/
return (
{content.map((latexCode) => (
))}
{plusMoreLines}
{language}
);
}
}
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
const codeVerticalPadding = Platform.select({
ios: 4,
android: 0,
});
return {
container: {
borderColor: changeOpacity(theme.centerChannelColor, 0.15),
borderRadius: 3,
borderWidth: StyleSheet.hairlineWidth,
flexDirection: 'row',
flex: 1,
},
rightColumn: {
flexDirection: 'column',
flex: 1,
paddingLeft: 6,
paddingVertical: 4,
},
code: {
flexDirection: 'row',
justifyContent: 'flex-start',
marginLeft: 5,
paddingVertical: codeVerticalPadding,
},
plusMoreLinesText: {
color: changeOpacity(theme.centerChannelColor, 0.4),
fontSize: 11,
marginTop: 2,
},
language: {
alignItems: 'center',
backgroundColor: theme.sidebarHeaderBg,
justifyContent: 'center',
opacity: 0.8,
padding: 6,
position: 'absolute',
right: 0,
top: 0,
},
languageText: {
color: theme.sidebarHeaderTextColor,
fontSize: 12,
},
errorText: {
fontSize: 14,
marginHorizontal: 5,
color: theme.errorTextColor,
},
};
});