1/**
2 * Copyright (c) 650 Industries.
3 * Copyright (c) Meta Platforms, Inc. and affiliates.
4 *
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8import React from 'react';
9import { StyleProp, Text, TextStyle } from 'react-native';
10
11import type { Message } from '../Data/parseLogBoxLog';
12
13type Props = {
14  message: Message;
15  style: StyleProp<TextStyle>;
16  plaintext?: boolean;
17  maxLength?: number;
18};
19
20const cleanContent = (content: string) =>
21  content.replace(/^(TransformError |Warning: (Warning: )?|Error: )/g, '');
22
23export function LogBoxMessage(props: Props): JSX.Element {
24  const { content, substitutions }: Message = props.message;
25
26  if (props.plaintext === true) {
27    return <Text>{cleanContent(content)}</Text>;
28  }
29
30  const maxLength = props.maxLength != null ? props.maxLength : Infinity;
31  const substitutionStyle: StyleProp<TextStyle> = props.style;
32  const elements: JSX.Element[] = [];
33  let length = 0;
34  const createUnderLength = (key: string | '-1', message: string, style?: StyleProp<TextStyle>) => {
35    let cleanMessage = cleanContent(message);
36
37    if (props.maxLength != null) {
38      cleanMessage = cleanMessage.slice(0, props.maxLength - length);
39    }
40
41    if (length < maxLength) {
42      elements.push(
43        <Text key={key} style={style}>
44          {cleanMessage}
45        </Text>
46      );
47    }
48
49    length += cleanMessage.length;
50  };
51
52  const lastOffset = substitutions.reduce((prevOffset, substitution, index) => {
53    const key = String(index);
54
55    if (substitution.offset > prevOffset) {
56      const prevPart = content.substr(prevOffset, substitution.offset - prevOffset);
57
58      createUnderLength(key, prevPart);
59    }
60
61    const substititionPart = content.substr(substitution.offset, substitution.length);
62
63    createUnderLength(key + '.5', substititionPart, substitutionStyle);
64    return substitution.offset + substitution.length;
65  }, 0);
66
67  if (lastOffset < content.length) {
68    const lastPart = content.substr(lastOffset);
69    createUnderLength('-1', lastPart);
70  }
71
72  return <>{elements}</>;
73}
74