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, { useState } from 'react'; 9import { StyleSheet, Text, View } from 'react-native'; 10import { useSelectedLog } from '../Data/LogContext'; 11import { LogBoxButton } from '../UI/LogBoxButton'; 12import * as LogBoxStyle from '../UI/LogBoxStyle'; 13import openFileInEditor from '../modules/openFileInEditor'; 14import { LogBoxInspectorSection } from './LogBoxInspectorSection'; 15import { LogBoxInspectorSourceMapStatus } from './LogBoxInspectorSourceMapStatus'; 16import { LogBoxInspectorStackFrame } from './LogBoxInspectorStackFrame'; 17export function getCollapseMessage(stackFrames, collapsed) { 18 if (stackFrames.length === 0) { 19 return 'No frames to show'; 20 } 21 const collapsedCount = stackFrames.reduce((count, { collapse }) => { 22 if (collapse === true) { 23 return count + 1; 24 } 25 return count; 26 }, 0); 27 if (collapsedCount === 0) { 28 return 'Showing all frames'; 29 } 30 const framePlural = `frame${collapsedCount > 1 ? 's' : ''}`; 31 if (collapsedCount === stackFrames.length) { 32 return collapsed 33 ? `See${collapsedCount > 1 ? ' all ' : ' '}${collapsedCount} collapsed ${framePlural}` 34 : `Collapse${collapsedCount > 1 ? ' all ' : ' '}${collapsedCount} ${framePlural}`; 35 } 36 else { 37 return collapsed 38 ? `See ${collapsedCount} more ${framePlural}` 39 : `Collapse ${collapsedCount} ${framePlural}`; 40 } 41} 42export function LogBoxInspectorStackFrames({ onRetry, type }) { 43 const log = useSelectedLog(); 44 const [collapsed, setCollapsed] = useState(() => { 45 // Only collapse frames initially if some frames are not collapsed. 46 return log.getAvailableStack(type)?.some(({ collapse }) => !collapse); 47 }); 48 function getStackList() { 49 if (collapsed === true) { 50 return log.getAvailableStack(type)?.filter(({ collapse }) => !collapse); 51 } 52 else { 53 return log.getAvailableStack(type); 54 } 55 } 56 if (log.getAvailableStack(type)?.length === 0) { 57 return null; 58 } 59 return (React.createElement(LogBoxInspectorSection, { heading: type === 'component' ? 'Component Stack' : 'Call Stack', action: React.createElement(LogBoxInspectorSourceMapStatus, { onPress: log.symbolicated[type].status === 'FAILED' ? onRetry : null, status: log.symbolicated[type].status }) }, 60 log.symbolicated[type].status !== 'COMPLETE' && (React.createElement(View, { style: stackStyles.hintBox }, 61 React.createElement(Text, { style: stackStyles.hintText }, "This call stack is not symbolicated. Some features are unavailable such as viewing the function name or tapping to open files."))), 62 React.createElement(StackFrameList, { list: getStackList(), status: log.symbolicated[type].status }), 63 React.createElement(StackFrameFooter, { onPress: () => setCollapsed(!collapsed), message: getCollapseMessage(log.getAvailableStack(type), !!collapsed) }))); 64} 65function StackFrameList({ list, status, }) { 66 return list.map((frame, index) => { 67 const { file, lineNumber } = frame; 68 return (React.createElement(LogBoxInspectorStackFrame, { key: index, frame: frame, onPress: status === 'COMPLETE' && file != null && lineNumber != null 69 ? () => openFileInEditor(file, lineNumber) 70 : undefined })); 71 }); 72} 73function StackFrameFooter({ message, onPress }) { 74 return (React.createElement(View, { style: stackStyles.collapseContainer }, 75 React.createElement(LogBoxButton, { backgroundColor: { 76 default: 'transparent', 77 pressed: LogBoxStyle.getBackgroundColor(1), 78 }, onPress: onPress, style: stackStyles.collapseButton }, 79 React.createElement(Text, { style: stackStyles.collapse }, message)))); 80} 81const stackStyles = StyleSheet.create({ 82 section: { 83 marginTop: 15, 84 }, 85 heading: { 86 alignItems: 'center', 87 flexDirection: 'row', 88 paddingHorizontal: 12, 89 marginBottom: 10, 90 }, 91 headingText: { 92 color: LogBoxStyle.getTextColor(1), 93 flex: 1, 94 fontSize: 20, 95 fontWeight: '600', 96 includeFontPadding: false, 97 lineHeight: 20, 98 }, 99 body: { 100 paddingBottom: 10, 101 }, 102 bodyText: { 103 color: LogBoxStyle.getTextColor(1), 104 fontSize: 14, 105 includeFontPadding: false, 106 lineHeight: 18, 107 fontWeight: '500', 108 paddingHorizontal: 27, 109 }, 110 hintText: { 111 color: LogBoxStyle.getTextColor(0.7), 112 fontSize: 13, 113 includeFontPadding: false, 114 lineHeight: 18, 115 fontWeight: '400', 116 marginHorizontal: 10, 117 }, 118 hintBox: { 119 backgroundColor: LogBoxStyle.getBackgroundColor(), 120 marginHorizontal: 10, 121 paddingHorizontal: 5, 122 paddingVertical: 10, 123 borderRadius: 5, 124 marginBottom: 5, 125 }, 126 collapseContainer: { 127 marginLeft: 15, 128 flexDirection: 'row', 129 }, 130 collapseButton: { 131 borderRadius: 5, 132 }, 133 collapse: { 134 color: LogBoxStyle.getTextColor(0.7), 135 fontSize: 12, 136 fontWeight: '300', 137 lineHeight: 20, 138 marginTop: 0, 139 paddingHorizontal: 10, 140 paddingVertical: 5, 141 }, 142}); 143//# sourceMappingURL=LogBoxInspectorStackFrames.js.map