UNPKG

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
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