react-native-debug-toolkit
Version:
A simple yet powerful debugging toolkit for React Native with a convenient floating UI for development
199 lines (184 loc) • 5.08 kB
JavaScript
import React, { useState, useMemo } from 'react'
import {
View,
Text,
StyleSheet,
FlatList,
TouchableOpacity,
} from 'react-native'
import NavigationLogDetails from './NavigationLogDetails'
import { getNavigationActionColor } from '../utils/DebugConst'
const SubViewNavigationLogs = ({ logs = [] }) => {
const [selectedLog, setSelectedLog] = useState(null)
// Memoize the sorted logs
const sortedLogs = useMemo(() => {
// Create a stable copy before sorting if FlatList relies on reference equality
return [...logs].sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
}, [logs]);
// Helper to format navigation data for preview
const formatNavigationPreview = (action, from, to) => {
const fromName = from?.name || 'Unknown';
const toName = to?.name || 'Unknown';
let preview = `${action || 'Navigate'}: ${fromName} → ${toName}`;
// Add params summary if available
if (to?.params) {
try {
const paramsStr = JSON.stringify(to.params);
const shortParams = paramsStr.length > 30 ? paramsStr.substring(0, 27) + '...' : paramsStr;
preview += ` ${shortParams}`;
} catch (e) {
preview += ' [with params]';
}
}
return preview;
};
const renderLogItem = ({ item }) => {
const action = item.action || 'navigate';
const actionColor = getNavigationActionColor(action);
const previewText = formatNavigationPreview(action, item.from, item.to);
const timestamp = item.timestamp
? new Date(item.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false })
: '';
return (
<TouchableOpacity
style={styles.logItem}
onPress={() => setSelectedLog(item)}>
<View style={styles.logItemContainer}>
<View
style={[styles.actionIndicator, { backgroundColor: actionColor }]}
/>
<View style={styles.logContent}>
<View style={styles.logHeader}>
<Text style={[styles.actionText, { color: actionColor }]}>
{action.toUpperCase()}
</Text>
<Text style={styles.time}>{timestamp}</Text>
</View>
<Text style={styles.logMessage} numberOfLines={2}>
{previewText}
</Text>
{item.duration && (
<Text style={styles.duration}>{`${item.duration} ms`}</Text>
)}
</View>
</View>
</TouchableOpacity>
)
}
// If a log is selected, show the details view
if (selectedLog) {
return (
<View style={styles.container}>
<View style={styles.detailsHeader}>
<TouchableOpacity
style={styles.backButton}
onPress={() => setSelectedLog(null)}>
<Text style={styles.backButtonText}>← Back</Text>
</TouchableOpacity>
<Text style={styles.headerTitle}>Navigation Details</Text>
</View>
<NavigationLogDetails log={selectedLog} />
</View>
)
}
// Otherwise show the list view
return (
<View style={styles.container}>
{sortedLogs.length === 0 ? (
<Text style={styles.emptyText}>No navigation events logged yet</Text>
) : (
<FlatList
data={sortedLogs}
renderItem={renderLogItem}
keyExtractor={(item, index) => `${item.timestamp}-${index}`}
style={styles.list}
/>
)}
</View>
)
}
// Adapted styles from SubViewConsoleLogs
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
list: {
flex: 1,
},
emptyText: {
textAlign: 'center',
color: '#999',
marginTop: 20,
},
logItem: {
borderBottomWidth: 1,
borderBottomColor: '#eee',
},
logItemContainer: {
flexDirection: 'row',
paddingVertical: 10,
paddingHorizontal: 12,
},
actionIndicator: {
width: 4,
borderRadius: 2,
marginRight: 10,
},
logContent: {
flex: 1,
},
logHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 5,
},
actionText: {
fontSize: 13,
fontWeight: 'bold',
},
time: {
fontSize: 12,
color: '#888',
},
logMessage: {
fontSize: 14,
color: '#333',
lineHeight: 18,
fontFamily: 'monospace',
},
duration: {
fontSize: 12,
color: '#888',
marginTop: 4,
},
// Details Header Styles
detailsHeader: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 10,
paddingHorizontal: 15,
borderBottomWidth: 1,
borderBottomColor: '#eee',
backgroundColor: '#f8f9fa',
},
backButton: {
paddingHorizontal: 10,
paddingVertical: 5,
borderRadius: 4,
backgroundColor: '#eee',
marginRight: 15,
},
backButtonText: {
color: '#333',
fontWeight: '500',
fontSize: 14,
},
headerTitle: {
fontSize: 16,
fontWeight: 'bold',
color: '#333',
},
})
export default SubViewNavigationLogs