126ad19fcSEvan Bacon/**
226ad19fcSEvan Bacon * Copyright (c) 650 Industries.
326ad19fcSEvan Bacon * Copyright (c) Meta Platforms, Inc. and affiliates.
426ad19fcSEvan Bacon *
526ad19fcSEvan Bacon * This source code is licensed under the MIT license found in the
626ad19fcSEvan Bacon * LICENSE file in the root directory of this source tree.
726ad19fcSEvan Bacon */
826ad19fcSEvan Baconimport React from 'react';
926ad19fcSEvan Baconimport { ScrollView, StyleSheet, Text, View } from 'react-native';
1026ad19fcSEvan Bacon
11*8a424bebSJames Ideimport { LogBoxInspectorSection } from './LogBoxInspectorSection';
1226ad19fcSEvan Baconimport type { CodeFrame } from '../Data/parseLogBoxLog';
1326ad19fcSEvan Baconimport { Ansi } from '../UI/AnsiHighlight';
1426ad19fcSEvan Baconimport { LogBoxButton } from '../UI/LogBoxButton';
1526ad19fcSEvan Baconimport * as LogBoxStyle from '../UI/LogBoxStyle';
1626ad19fcSEvan Baconimport { CODE_FONT } from '../UI/constants';
1726ad19fcSEvan Baconimport { formatProjectFilePath } from '../formatProjectFilePath';
1826ad19fcSEvan Baconimport openFileInEditor from '../modules/openFileInEditor';
1926ad19fcSEvan Bacon
2026ad19fcSEvan Bacondeclare const process: any;
2126ad19fcSEvan Bacon
2226ad19fcSEvan Baconexport function LogBoxInspectorCodeFrame({ codeFrame }: { codeFrame?: CodeFrame }) {
2326ad19fcSEvan Bacon  if (codeFrame == null) {
2426ad19fcSEvan Bacon    return null;
2526ad19fcSEvan Bacon  }
2626ad19fcSEvan Bacon
2726ad19fcSEvan Bacon  function getFileName() {
2826ad19fcSEvan Bacon    return formatProjectFilePath(process.env.EXPO_PROJECT_ROOT, codeFrame?.fileName);
2926ad19fcSEvan Bacon  }
3026ad19fcSEvan Bacon
3126ad19fcSEvan Bacon  function getLocation() {
3226ad19fcSEvan Bacon    const location = codeFrame?.location;
3326ad19fcSEvan Bacon    if (location != null) {
3426ad19fcSEvan Bacon      return ` (${location.row}:${location.column + 1 /* Code frame columns are zero indexed */})`;
3526ad19fcSEvan Bacon    }
3626ad19fcSEvan Bacon
3726ad19fcSEvan Bacon    return null;
3826ad19fcSEvan Bacon  }
3926ad19fcSEvan Bacon
4026ad19fcSEvan Bacon  return (
4126ad19fcSEvan Bacon    <LogBoxInspectorSection heading="Source">
4226ad19fcSEvan Bacon      <View style={styles.box}>
4326ad19fcSEvan Bacon        <View style={styles.frame}>
4426ad19fcSEvan Bacon          <ScrollView horizontal>
4526ad19fcSEvan Bacon            <Ansi style={styles.content} text={codeFrame.content} />
4626ad19fcSEvan Bacon          </ScrollView>
4726ad19fcSEvan Bacon        </View>
4826ad19fcSEvan Bacon        <LogBoxButton
4926ad19fcSEvan Bacon          backgroundColor={{
5026ad19fcSEvan Bacon            default: 'transparent',
5126ad19fcSEvan Bacon            pressed: LogBoxStyle.getBackgroundDarkColor(1),
5226ad19fcSEvan Bacon          }}
5326ad19fcSEvan Bacon          style={styles.button}
5426ad19fcSEvan Bacon          onPress={() => {
5526ad19fcSEvan Bacon            openFileInEditor(codeFrame.fileName, codeFrame.location?.row ?? 0);
5626ad19fcSEvan Bacon          }}>
5726ad19fcSEvan Bacon          <Text style={styles.fileText}>
5826ad19fcSEvan Bacon            {getFileName()}
5926ad19fcSEvan Bacon            {getLocation()}
6026ad19fcSEvan Bacon          </Text>
6126ad19fcSEvan Bacon        </LogBoxButton>
6226ad19fcSEvan Bacon      </View>
6326ad19fcSEvan Bacon    </LogBoxInspectorSection>
6426ad19fcSEvan Bacon  );
6526ad19fcSEvan Bacon}
6626ad19fcSEvan Bacon
6726ad19fcSEvan Baconconst styles = StyleSheet.create({
6826ad19fcSEvan Bacon  box: {
6926ad19fcSEvan Bacon    backgroundColor: LogBoxStyle.getBackgroundColor(),
7026ad19fcSEvan Bacon    borderWidth: 1,
7126ad19fcSEvan Bacon    borderColor: '#323232',
7226ad19fcSEvan Bacon    marginLeft: 10,
7326ad19fcSEvan Bacon    marginRight: 10,
7426ad19fcSEvan Bacon    marginTop: 5,
7526ad19fcSEvan Bacon    borderRadius: 3,
7626ad19fcSEvan Bacon  },
7726ad19fcSEvan Bacon  frame: {
7826ad19fcSEvan Bacon    padding: 10,
7926ad19fcSEvan Bacon    borderBottomColor: LogBoxStyle.getTextColor(0.1),
8026ad19fcSEvan Bacon    borderBottomWidth: 1,
8126ad19fcSEvan Bacon  },
8226ad19fcSEvan Bacon  button: {
8326ad19fcSEvan Bacon    paddingTop: 10,
8426ad19fcSEvan Bacon    paddingBottom: 10,
8526ad19fcSEvan Bacon  },
8626ad19fcSEvan Bacon  content: {
8726ad19fcSEvan Bacon    color: LogBoxStyle.getTextColor(1),
8826ad19fcSEvan Bacon    fontSize: 12,
8926ad19fcSEvan Bacon    includeFontPadding: false,
9026ad19fcSEvan Bacon    lineHeight: 20,
9126ad19fcSEvan Bacon    fontFamily: CODE_FONT,
9226ad19fcSEvan Bacon  },
9326ad19fcSEvan Bacon  fileText: {
9426ad19fcSEvan Bacon    userSelect: 'none',
9526ad19fcSEvan Bacon    color: LogBoxStyle.getTextColor(0.5),
9626ad19fcSEvan Bacon    textAlign: 'center',
9726ad19fcSEvan Bacon    flex: 1,
9826ad19fcSEvan Bacon    fontSize: 16,
9926ad19fcSEvan Bacon    includeFontPadding: false,
10026ad19fcSEvan Bacon    fontFamily: CODE_FONT,
10126ad19fcSEvan Bacon  },
10226ad19fcSEvan Bacon});
103