Skip to content
28 changes: 13 additions & 15 deletions packages/react-native/Libraries/LogBox/UI/LogBoxButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import * as LogBoxStyle from './LogBoxStyle';
import * as React from 'react';
import {useState} from 'react';

type Props = Readonly<{
component LogBoxButton(
id?: string,
backgroundColor: Readonly<{
default: string,
Expand All @@ -29,40 +29,38 @@ type Props = Readonly<{
hitSlop?: ?EdgeInsetsProp,
onPress?: ?(event: GestureResponderEvent) => void,
style?: ViewStyleProp,
}>;

function LogBoxButton(props: Props): React.Node {
) {
const [pressed, setPressed] = useState(false);

let backgroundColor = props.backgroundColor;
if (!backgroundColor) {
backgroundColor = {
let resolvedBackgroundColor = backgroundColor;
if (!resolvedBackgroundColor) {
resolvedBackgroundColor = {
default: LogBoxStyle.getBackgroundColor(0.95),
pressed: LogBoxStyle.getBackgroundColor(0.6),
};
}

const content = (
<View
id={props.id}
id={id}
style={StyleSheet.compose(
{
backgroundColor: pressed
? backgroundColor.pressed
: backgroundColor.default,
? resolvedBackgroundColor.pressed
: resolvedBackgroundColor.default,
},
props.style,
style,
)}>
{props.children}
{children}
</View>
);

return props.onPress == null ? (
return onPress == null ? (
content
) : (
<TouchableWithoutFeedback
hitSlop={props.hitSlop}
onPress={props.onPress}
hitSlop={hitSlop}
onPress={onPress}
onPressIn={() => setPressed(true)}
onPressOut={() => setPressed(false)}>
{content}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,7 @@ import LogBoxInspectorSection from './LogBoxInspectorSection';
import * as LogBoxStyle from './LogBoxStyle';
import * as React from 'react';

type Props = Readonly<{
componentCodeFrame: ?CodeFrame,
codeFrame: ?CodeFrame,
}>;

function CodeFrameDisplay({codeFrame}: {codeFrame: CodeFrame}): React.Node {
component CodeFrameDisplay(codeFrame: CodeFrame) {
function getFileName() {
// $FlowFixMe[incompatible-use]
const matches = /[^/]*$/.exec(codeFrame.fileName);
Expand Down Expand Up @@ -77,8 +72,10 @@ function CodeFrameDisplay({codeFrame}: {codeFrame: CodeFrame}): React.Node {
);
}

function LogBoxInspectorCodeFrame(props: Props): React.Node {
const {codeFrame, componentCodeFrame} = props;
component LogBoxInspectorCodeFrame(
componentCodeFrame: ?CodeFrame,
codeFrame: ?CodeFrame,
) {
let sources = [];
if (codeFrame != null) {
sources.push(codeFrame);
Expand All @@ -103,7 +100,7 @@ function LogBoxInspectorCodeFrame(props: Props): React.Node {
);
}

function AppInfo() {
component AppInfo() {
const appInfo = LogBoxData.getAppInfo();
if (appInfo == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,21 @@ import LogBoxMessage from './LogBoxMessage';
import * as LogBoxStyle from './LogBoxStyle';
import * as React from 'react';

type Props = Readonly<{
const SHOW_MORE_MESSAGE_LENGTH = 300;

component LogBoxInspectorMessageHeader(
collapsed: boolean,
message: Message,
level: LogLevel,
title: string,
onPress: () => void,
}>;

const SHOW_MORE_MESSAGE_LENGTH = 300;

function LogBoxInspectorMessageHeader(props: Props): React.Node {
) {
function renderShowMore() {
if (
props.message.content.length < SHOW_MORE_MESSAGE_LENGTH ||
!props.collapsed
) {
if (message.content.length < SHOW_MORE_MESSAGE_LENGTH || !collapsed) {
return null;
}
return (
<Text style={messageStyles.collapse} onPress={() => props.onPress()}>
<Text style={messageStyles.collapse} onPress={() => onPress()}>
... See More
</Text>
);
Expand All @@ -47,15 +42,15 @@ function LogBoxInspectorMessageHeader(props: Props): React.Node {
<View style={messageStyles.body}>
<View style={messageStyles.heading}>
<Text
style={[messageStyles.headingText, messageStyles[props.level]]}
style={[messageStyles.headingText, messageStyles[level]]}
id="logbox_message_title_text">
{props.title}
{title}
</Text>
</View>
<Text style={messageStyles.bodyText} id="logbox_message_contents_text">
<LogBoxMessage
maxLength={props.collapsed ? SHOW_MORE_MESSAGE_LENGTH : Infinity}
message={props.message}
maxLength={collapsed ? SHOW_MORE_MESSAGE_LENGTH : Infinity}
message={message}
style={messageStyles.messageText}
/>
{renderShowMore()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ import * as LogBoxStyle from './LogBoxStyle';
import * as React from 'react';
import {useState} from 'react';

type Props = Readonly<{
log: LogBoxLog,
}>;

const BEFORE_SLASH_RE = /^(.*)[\\/]/;

// Taken from React https://github.com/facebook/react/blob/206d61f72214e8ae5b935f0bf8628491cb7f0797/packages/react-devtools-shared/src/backend/describeComponentFrame.js#L27-L41
Expand All @@ -49,29 +45,30 @@ function getPrettyFileName(path: string) {

return fileName;
}
function LogBoxInspectorReactFrames(props: Props): React.Node {

component LogBoxInspectorReactFrames(log: LogBoxLog) {
const [collapsed, setCollapsed] = useState(true);
if (
props.log.getAvailableComponentStack() == null ||
props.log.getAvailableComponentStack().length < 1
log.getAvailableComponentStack() == null ||
log.getAvailableComponentStack().length < 1
) {
return null;
}

function getStackList() {
if (collapsed) {
return props.log.getAvailableComponentStack().slice(0, 3);
return log.getAvailableComponentStack().slice(0, 3);
} else {
return props.log.getAvailableComponentStack();
return log.getAvailableComponentStack();
}
}

function getCollapseMessage() {
if (props.log.getAvailableComponentStack().length <= 3) {
if (log.getAvailableComponentStack().length <= 3) {
return;
}

const count = props.log.getAvailableComponentStack().length - 3;
const count = log.getAvailableComponentStack().length - 3;
if (collapsed) {
return `See ${count} more components`;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,17 @@ import * as LogBoxStyle from './LogBoxStyle';
import * as React from 'react';
import {useEffect, useState} from 'react';

type Props = Readonly<{
component LogBoxInspectorSourceMapStatus(
onPress?: ?(event: GestureResponderEvent) => void,
status: 'COMPLETE' | 'FAILED' | 'NONE' | 'PENDING',
}>;

function LogBoxInspectorSourceMapStatus(props: Props): React.Node {
) {
const [state, setState] = useState({
animation: null,
rotate: null,
});

useEffect(() => {
if (props.status === 'PENDING') {
if (status === 'PENDING') {
if (state.animation == null) {
const animated = new Animated.Value(0);
const animation = Animated.loop(
Expand Down Expand Up @@ -67,11 +65,11 @@ function LogBoxInspectorSourceMapStatus(props: Props): React.Node {
state.animation.stop();
}
};
}, [props.status, state.animation]);
}, [status, state.animation]);

let image;
let color;
switch (props.status) {
switch (status) {
case 'FAILED':
image = require('./LogBoxImages/alert-triangle.png');
color = LogBoxStyle.getErrorColor(1);
Expand All @@ -82,7 +80,7 @@ function LogBoxInspectorSourceMapStatus(props: Props): React.Node {
break;
}

if (props.status === 'COMPLETE' || image == null) {
if (status === 'COMPLETE' || image == null) {
return null;
}

Expand All @@ -93,14 +91,14 @@ function LogBoxInspectorSourceMapStatus(props: Props): React.Node {
pressed: LogBoxStyle.getBackgroundColor(1),
}}
hitSlop={{bottom: 8, left: 8, right: 8, top: 8}}
onPress={props.onPress}
onPress={onPress}
style={styles.root}>
<Animated.Image
source={image}
style={[
styles.image,
{tintColor: color},
state.rotate == null || props.status !== 'PENDING'
state.rotate == null || status !== 'PENDING'
? null
: {transform: [{rotate: state.rotate}]},
]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,10 @@ import LogBoxButton from './LogBoxButton';
import * as LogBoxStyle from './LogBoxStyle';
import * as React from 'react';

type Props = Readonly<{
component LogBoxInspectorStackFrame(
frame: StackFrame,
onPress?: ?(event: GestureResponderEvent) => void,
}>;

function LogBoxInspectorStackFrame(props: Props): React.Node {
const {frame, onPress} = props;
) {
const column = frame.column != null && parseInt(frame.column, 10);
const location =
getFileName(frame.file) +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ import * as LogBoxStyle from './LogBoxStyle';
import * as React from 'react';
import {useState} from 'react';

type Props = Readonly<{
log: LogBoxLog,
onRetry: () => void,
}>;

export function getCollapseMessage(
stackFrames: Stack,
collapsed: boolean,
Expand Down Expand Up @@ -65,21 +60,21 @@ export function getCollapseMessage(
}
}

function LogBoxInspectorStackFrames(props: Props): React.Node {
component LogBoxInspectorStackFrames(log: LogBoxLog, onRetry: () => void) {
const [collapsed, setCollapsed] = useState(() => {
// Only collapse frames initially if some frames are not collapsed.
return props.log.getAvailableStack().some(({collapse}) => !collapse);
return log.getAvailableStack().some(({collapse}) => !collapse);
});

function getStackList() {
if (collapsed === true) {
return props.log.getAvailableStack().filter(({collapse}) => !collapse);
return log.getAvailableStack().filter(({collapse}) => !collapse);
} else {
return props.log.getAvailableStack();
return log.getAvailableStack();
}
}

if (props.log.getAvailableStack().length === 0) {
if (log.getAvailableStack().length === 0) {
return null;
}

Expand All @@ -88,46 +83,41 @@ function LogBoxInspectorStackFrames(props: Props): React.Node {
heading="Call Stack"
action={
<LogBoxInspectorSourceMapStatus
onPress={
props.log.symbolicated.status === 'FAILED' ? props.onRetry : null
}
status={props.log.symbolicated.status}
onPress={log.symbolicated.status === 'FAILED' ? onRetry : null}
status={log.symbolicated.status}
/>
}>
{props.log.symbolicated.status !== 'COMPLETE' && (
{log.symbolicated.status !== 'COMPLETE' && (
<View style={stackStyles.hintBox}>
<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.
</Text>
</View>
)}
<StackFrameList
list={getStackList()}
status={props.log.symbolicated.status}
/>
<StackFrameList list={getStackList()} status={log.symbolicated.status} />
<StackFrameFooter
onPress={() => setCollapsed(!collapsed)}
message={getCollapseMessage(props.log.getAvailableStack(), collapsed)}
message={getCollapseMessage(log.getAvailableStack(), collapsed)}
/>
</LogBoxInspectorSection>
);
}

function StackFrameList(props: {
component StackFrameList(
list: Stack | Array<StackFrame>,
status: string | 'COMPLETE' | 'FAILED' | 'NONE' | 'PENDING',
}) {
) {
return (
<>
{props.list.map((frame, index) => {
{list.map((frame, index) => {
const {file, lineNumber} = frame;
return (
<LogBoxInspectorStackFrame
key={index}
frame={frame}
onPress={
props.status === 'COMPLETE' && file != null && lineNumber != null
status === 'COMPLETE' && file != null && lineNumber != null
? () => openFileInEditor(file, lineNumber)
: null
}
Expand All @@ -138,19 +128,17 @@ function StackFrameList(props: {
);
}

function StackFrameFooter(
props: Readonly<{message: string, onPress: () => void}>,
) {
component StackFrameFooter(message: string, onPress: () => void) {
return (
<View style={stackStyles.collapseContainer}>
<LogBoxButton
backgroundColor={{
default: 'transparent',
pressed: LogBoxStyle.getBackgroundColor(1),
}}
onPress={props.onPress}
onPress={onPress}
style={stackStyles.collapseButton}>
<Text style={stackStyles.collapse}>{props.message}</Text>
<Text style={stackStyles.collapse}>{message}</Text>
</LogBoxButton>
</View>
);
Expand Down
Loading
Loading