223 lines
5.3 KiB
JavaScript
223 lines
5.3 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow strict-local
|
|
* @format
|
|
*/
|
|
|
|
import type {Message as MessageType} from '../Data/parseLogBoxLog';
|
|
|
|
import View from '../../Components/View/View';
|
|
import Image from '../../Image/Image';
|
|
import StyleSheet from '../../StyleSheet/StyleSheet';
|
|
import Text from '../../Text/Text';
|
|
import * as LogBoxData from '../Data/LogBoxData';
|
|
import LogBoxLog from '../Data/LogBoxLog';
|
|
import LogBoxButton from './LogBoxButton';
|
|
import LogBoxMessage from './LogBoxMessage';
|
|
import * as LogBoxStyle from './LogBoxStyle';
|
|
import * as React from 'react';
|
|
|
|
type Props = $ReadOnly<{
|
|
log: LogBoxLog,
|
|
totalLogCount: number,
|
|
level: 'warn' | 'error',
|
|
onPressOpen: () => void,
|
|
onPressDismiss: () => void,
|
|
}>;
|
|
|
|
function LogBoxLogNotification(props: Props): React.Node {
|
|
const {totalLogCount, level, log} = props;
|
|
|
|
// Eagerly symbolicate so the stack is available when pressing to inspect.
|
|
React.useEffect(() => {
|
|
LogBoxData.symbolicateLogLazy(log);
|
|
}, [log]);
|
|
|
|
return (
|
|
<View style={toastStyles.container}>
|
|
<LogBoxButton
|
|
onPress={props.onPressOpen}
|
|
style={toastStyles.press}
|
|
backgroundColor={{
|
|
default: LogBoxStyle.getBackgroundColor(1),
|
|
pressed: LogBoxStyle.getBackgroundColor(0.9),
|
|
}}>
|
|
<View style={toastStyles.content}>
|
|
<CountBadge count={totalLogCount} level={level} />
|
|
<Message message={log.message} />
|
|
<DismissButton onPress={props.onPressDismiss} />
|
|
</View>
|
|
</LogBoxButton>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
function CountBadge(props: {count: number, level: 'error' | 'warn'}) {
|
|
return (
|
|
<View style={countStyles.outside}>
|
|
{/* $FlowFixMe[incompatible-type] (>=0.114.0) This suppression was added
|
|
* when fixing the type of `StyleSheet.create`. Remove this comment to
|
|
* see the error. */}
|
|
<View style={[countStyles.inside, countStyles[props.level]]}>
|
|
<Text style={countStyles.text}>
|
|
{props.count <= 1 ? '!' : props.count}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
function Message(props: {message: MessageType}) {
|
|
return (
|
|
<View style={messageStyles.container}>
|
|
<Text numberOfLines={1} style={messageStyles.text}>
|
|
{props.message && (
|
|
<LogBoxMessage
|
|
plaintext
|
|
message={props.message}
|
|
style={messageStyles.substitutionText}
|
|
/>
|
|
)}
|
|
</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
function DismissButton(props: {onPress: () => void}) {
|
|
return (
|
|
<View style={dismissStyles.container}>
|
|
<LogBoxButton
|
|
backgroundColor={{
|
|
default: LogBoxStyle.getTextColor(0.3),
|
|
pressed: LogBoxStyle.getTextColor(0.5),
|
|
}}
|
|
hitSlop={{
|
|
top: 12,
|
|
right: 10,
|
|
bottom: 12,
|
|
left: 10,
|
|
}}
|
|
onPress={props.onPress}
|
|
style={dismissStyles.press}>
|
|
<Image
|
|
source={require('./LogBoxImages/close.png')}
|
|
style={dismissStyles.image}
|
|
/>
|
|
</LogBoxButton>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const countStyles = StyleSheet.create({
|
|
warn: {
|
|
backgroundColor: LogBoxStyle.getWarningColor(1),
|
|
},
|
|
error: {
|
|
backgroundColor: LogBoxStyle.getErrorColor(1),
|
|
},
|
|
log: {
|
|
backgroundColor: LogBoxStyle.getLogColor(1),
|
|
},
|
|
outside: {
|
|
padding: 2,
|
|
borderRadius: 25,
|
|
backgroundColor: '#fff',
|
|
marginRight: 8,
|
|
},
|
|
inside: {
|
|
minWidth: 18,
|
|
paddingLeft: 4,
|
|
paddingRight: 4,
|
|
borderRadius: 25,
|
|
fontWeight: '600',
|
|
},
|
|
text: {
|
|
color: LogBoxStyle.getTextColor(1),
|
|
fontSize: 14,
|
|
lineHeight: 18,
|
|
textAlign: 'center',
|
|
fontWeight: '600',
|
|
textShadowColor: LogBoxStyle.getBackgroundColor(0.4),
|
|
textShadowOffset: {width: 0, height: 0},
|
|
textShadowRadius: 3,
|
|
},
|
|
});
|
|
|
|
const messageStyles = StyleSheet.create({
|
|
container: {
|
|
alignSelf: 'stretch',
|
|
flexGrow: 1,
|
|
flexShrink: 1,
|
|
flexBasis: 'auto',
|
|
borderLeftColor: LogBoxStyle.getTextColor(0.2),
|
|
borderLeftWidth: 1,
|
|
paddingLeft: 8,
|
|
},
|
|
text: {
|
|
color: LogBoxStyle.getTextColor(1),
|
|
flex: 1,
|
|
fontSize: 14,
|
|
lineHeight: 22,
|
|
},
|
|
substitutionText: {
|
|
color: LogBoxStyle.getTextColor(0.6),
|
|
},
|
|
});
|
|
|
|
const dismissStyles = StyleSheet.create({
|
|
container: {
|
|
alignSelf: 'center',
|
|
flexDirection: 'row',
|
|
flexGrow: 0,
|
|
flexShrink: 0,
|
|
flexBasis: 'auto',
|
|
marginLeft: 5,
|
|
},
|
|
press: {
|
|
height: 20,
|
|
width: 20,
|
|
borderRadius: 25,
|
|
alignSelf: 'flex-end',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
image: {
|
|
height: 8,
|
|
width: 8,
|
|
tintColor: LogBoxStyle.getBackgroundColor(1),
|
|
},
|
|
});
|
|
|
|
const toastStyles = StyleSheet.create({
|
|
container: {
|
|
height: 48,
|
|
position: 'relative',
|
|
width: '100%',
|
|
justifyContent: 'center',
|
|
marginTop: 0.5,
|
|
backgroundColor: LogBoxStyle.getTextColor(1),
|
|
},
|
|
press: {
|
|
height: 48,
|
|
position: 'relative',
|
|
width: '100%',
|
|
justifyContent: 'center',
|
|
marginTop: 0.5,
|
|
paddingHorizontal: 12,
|
|
},
|
|
content: {
|
|
alignItems: 'flex-start',
|
|
flexDirection: 'row',
|
|
borderRadius: 8,
|
|
flexGrow: 0,
|
|
flexShrink: 0,
|
|
flexBasis: 'auto',
|
|
},
|
|
});
|
|
|
|
export default LogBoxLogNotification;
|