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 { ScrollView, StyleSheet, Text, View } from 'react-native';
10
11import { LogBoxInspectorSection } from './LogBoxInspectorSection';
12import type { CodeFrame } from '../Data/parseLogBoxLog';
13import { Ansi } from '../UI/AnsiHighlight';
14import { LogBoxButton } from '../UI/LogBoxButton';
15import * as LogBoxStyle from '../UI/LogBoxStyle';
16import { CODE_FONT } from '../UI/constants';
17import { formatProjectFilePath } from '../formatProjectFilePath';
18import openFileInEditor from '../modules/openFileInEditor';
19
20declare const process: any;
21
22export function LogBoxInspectorCodeFrame({ codeFrame }: { codeFrame?: CodeFrame }) {
23  if (codeFrame == null) {
24    return null;
25  }
26
27  function getFileName() {
28    return formatProjectFilePath(process.env.EXPO_PROJECT_ROOT, codeFrame?.fileName);
29  }
30
31  function getLocation() {
32    const location = codeFrame?.location;
33    if (location != null) {
34      return ` (${location.row}:${location.column + 1 /* Code frame columns are zero indexed */})`;
35    }
36
37    return null;
38  }
39
40  return (
41    <LogBoxInspectorSection heading="Source">
42      <View style={styles.box}>
43        <View style={styles.frame}>
44          <ScrollView horizontal>
45            <Ansi style={styles.content} text={codeFrame.content} />
46          </ScrollView>
47        </View>
48        <LogBoxButton
49          backgroundColor={{
50            default: 'transparent',
51            pressed: LogBoxStyle.getBackgroundDarkColor(1),
52          }}
53          style={styles.button}
54          onPress={() => {
55            openFileInEditor(codeFrame.fileName, codeFrame.location?.row ?? 0);
56          }}>
57          <Text style={styles.fileText}>
58            {getFileName()}
59            {getLocation()}
60          </Text>
61        </LogBoxButton>
62      </View>
63    </LogBoxInspectorSection>
64  );
65}
66
67const styles = StyleSheet.create({
68  box: {
69    backgroundColor: LogBoxStyle.getBackgroundColor(),
70    borderWidth: 1,
71    borderColor: '#323232',
72    marginLeft: 10,
73    marginRight: 10,
74    marginTop: 5,
75    borderRadius: 3,
76  },
77  frame: {
78    padding: 10,
79    borderBottomColor: LogBoxStyle.getTextColor(0.1),
80    borderBottomWidth: 1,
81  },
82  button: {
83    paddingTop: 10,
84    paddingBottom: 10,
85  },
86  content: {
87    color: LogBoxStyle.getTextColor(1),
88    fontSize: 12,
89    includeFontPadding: false,
90    lineHeight: 20,
91    fontFamily: CODE_FONT,
92  },
93  fileText: {
94    userSelect: 'none',
95    color: LogBoxStyle.getTextColor(0.5),
96    textAlign: 'center',
97    flex: 1,
98    fontSize: 16,
99    includeFontPadding: false,
100    fontFamily: CODE_FONT,
101  },
102});
103