react-native-debug-toolkit 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,41 @@
1
+ ---
2
+ description:
3
+ globs:
4
+ alwaysApply: false
5
+ ---
6
+
7
+ You are an expert in TypeScript, React Native, Expo, and Mobile App Development.
8
+
9
+ Code Style and Structure:
10
+ - Write concise, type-safe TypeScript code.
11
+ - Use functional components and hooks over class components.
12
+ - Ensure components are modular, reusable, and maintainable.
13
+ - Organize files by feature, grouping related components, hooks, and styles.
14
+
15
+ Naming Conventions:
16
+ - Use camelCase for variable and function names (e.g., `isFetchingData`, `handleUserInput`).
17
+ - Use PascalCase for component names (e.g., `UserProfile`, `ChatScreen`).
18
+
19
+ TypeScript Usage:
20
+ - Use TypeScript for all components, favoring interfaces for props and state.
21
+ - Enable strict typing in `tsconfig.json`.
22
+ - Avoid using `any`; strive for precise types.
23
+ - Utilize `React.FC` for defining functional components with props.
24
+
25
+ Performance Optimization:
26
+ - Minimize `useEffect`, `useState`, and heavy computations inside render methods.
27
+ - Use `React.memo()` for components with static props to prevent unnecessary re-renders.
28
+ - Optimize FlatLists with props like `removeClippedSubviews`, `maxToRenderPerBatch`, and `windowSize`.
29
+ - Use `getItemLayout` for FlatLists when items have a consistent size to improve performance.
30
+ - Avoid anonymous functions in `renderItem` or event handlers to prevent re-renders.
31
+
32
+ UI and Styling:
33
+ - Use consistent styling, either through `StyleSheet.create()` or Styled Components.
34
+ - Ensure responsive design by considering different screen sizes and orientations.
35
+ - Optimize image handling using libraries designed for React Native
36
+
37
+ Best Practices:
38
+ - Follow React Native's threading model to ensure smooth UI performance.
39
+ - Utilize CodePush Build and Updates for continuous deployment and Over-The-Air (OTA) updates.
40
+ - Use React Navigation for handling navigation and deep linking with best practices.
41
+
@@ -38,10 +38,17 @@ const CollapsibleSection = ({ title, children, initiallyExpanded = false }) => {
38
38
 
39
39
  const LongTextContent = ({ text }) => {
40
40
  return (
41
- <View style={styles.longTextContainer}>
42
- <Text style={styles.jsonString} selectable={true}>
43
- {text}
44
- </Text>
41
+ <View style={styles.longTextWrapper}>
42
+ <ScrollView
43
+ style={styles.longTextContainer}
44
+ contentContainerStyle={styles.longTextContent}
45
+ showsVerticalScrollIndicator={true}
46
+ nestedScrollEnabled={true}
47
+ bounces={false}>
48
+ <Text style={styles.jsonString} selectable={true}>
49
+ {text}
50
+ </Text>
51
+ </ScrollView>
45
52
  </View>
46
53
  )
47
54
  }
@@ -279,8 +286,7 @@ const HttpLogDetails = ({ log }) => {
279
286
  contentContainerStyle={styles.contentContainer}
280
287
  showsVerticalScrollIndicator={true}
281
288
  scrollEventThrottle={16}
282
- keyboardShouldPersistTaps='handled'
283
- nestedScrollEnabled={true}>
289
+ keyboardShouldPersistTaps='handled'>
284
290
  <View style={styles.header}>
285
291
  <View style={styles.headerInfo}>
286
292
  <Text style={styles.url} numberOfLines={2} selectable={true}>
@@ -295,6 +301,7 @@ const HttpLogDetails = ({ log }) => {
295
301
  {(request.method || 'GET').toUpperCase()}
296
302
  </Text>
297
303
  {status && <ApiStatus status={status} success={success} />}
304
+ {duration && <Text style={styles.duration}>(duration:{duration}ms)</Text>}
298
305
  </View>
299
306
  </View>
300
307
  <CopyButton text={request.url || ''} />
@@ -316,15 +323,27 @@ const HttpLogDetails = ({ log }) => {
316
323
  }
317
324
  />
318
325
  </View>
319
- <View style={styles.dataContent}>
320
- <JSONValue value={requestData} maxExpandLevel={1} />
326
+ <View style={styles.dataContentWrapper}>
327
+ <ScrollView
328
+ style={styles.dataContent}
329
+ nestedScrollEnabled={true}
330
+ bounces={false}
331
+ showsVerticalScrollIndicator={true}>
332
+ <JSONValue value={requestData} maxExpandLevel={1} />
333
+ </ScrollView>
321
334
  </View>
322
335
  </View>
323
336
  )}
324
337
 
325
338
  <CollapsibleSection title='Headers'>
326
- <View style={styles.dataContent}>
327
- <JSONValue value={request.headers || {}} maxExpandLevel={0} />
339
+ <View style={styles.dataContentWrapper}>
340
+ <ScrollView
341
+ style={styles.dataContent}
342
+ nestedScrollEnabled={true}
343
+ bounces={false}
344
+ showsVerticalScrollIndicator={true}>
345
+ <JSONValue value={request.headers || {}} maxExpandLevel={0} />
346
+ </ScrollView>
328
347
  </View>
329
348
  </CollapsibleSection>
330
349
  </View>
@@ -334,20 +353,12 @@ const HttpLogDetails = ({ log }) => {
334
353
  title={`Response ${responseSize}`}
335
354
  initiallyExpanded={true}>
336
355
  <View style={styles.content}>
337
- <View style={styles.row}>
338
- <Text style={styles.label}>Status:</Text>
339
- <Text style={styles.value}>
340
- {status || (success === false ? 'Error' : 'Unknown')}
341
- {status && response.statusText ? ` (${response.statusText})` : ''}
356
+ {/* <View style={styles.row}>
357
+ <Text style={styles.label}>Status: {status || (success === false ? 'Error' : 'Unknown')}
358
+ {status && response.statusText ? ` (${response.statusText})` : ''}
359
+ {duration && ` Duration: (${duration}ms)`}
342
360
  </Text>
343
- </View>
344
-
345
- {duration && (
346
- <View style={styles.row}>
347
- <Text style={styles.label}>Duration:</Text>
348
- <Text style={styles.value}>{duration}ms</Text>
349
- </View>
350
- )}
361
+ </View> */}
351
362
 
352
363
  {error && (
353
364
  <View style={styles.errorSection}>
@@ -370,15 +381,27 @@ const HttpLogDetails = ({ log }) => {
370
381
  }
371
382
  />
372
383
  </View>
373
- <View style={styles.dataContent}>
374
- <JSONValue value={responseData} maxExpandLevel={1} />
384
+ <View style={styles.dataContentWrapper}>
385
+ <ScrollView
386
+ style={styles.dataContent}
387
+ nestedScrollEnabled={true}
388
+ bounces={false}
389
+ showsVerticalScrollIndicator={true}>
390
+ <JSONValue value={responseData} maxExpandLevel={1} />
391
+ </ScrollView>
375
392
  </View>
376
393
  </View>
377
394
  )}
378
395
 
379
396
  <CollapsibleSection title='Headers'>
380
- <View style={styles.dataContent}>
381
- <JSONValue value={response.headers || {}} maxExpandLevel={0} />
397
+ <View style={styles.dataContentWrapper}>
398
+ <ScrollView
399
+ style={styles.dataContent}
400
+ nestedScrollEnabled={true}
401
+ bounces={false}
402
+ showsVerticalScrollIndicator={true}>
403
+ <JSONValue value={response.headers || {}} maxExpandLevel={0} />
404
+ </ScrollView>
382
405
  </View>
383
406
  </CollapsibleSection>
384
407
  </View>
@@ -391,10 +414,16 @@ const HttpLogDetails = ({ log }) => {
391
414
  <Text style={styles.codeBlockLabel}>Debug with cURL</Text>
392
415
  <CopyButton text={generateCurl()} />
393
416
  </View>
394
- <View style={styles.codeBlock}>
395
- <Text style={styles.codeText} selectable={true}>
396
- {generateCurl()}
397
- </Text>
417
+ <View style={styles.dataContentWrapper}>
418
+ <ScrollView
419
+ style={styles.codeBlock}
420
+ nestedScrollEnabled={true}
421
+ bounces={false}
422
+ showsVerticalScrollIndicator={true}>
423
+ <Text style={styles.codeText} selectable={true}>
424
+ {generateCurl()}
425
+ </Text>
426
+ </ScrollView>
398
427
  </View>
399
428
  </View>
400
429
  </View>
@@ -555,7 +584,11 @@ const styles = StyleSheet.create({
555
584
  fontWeight: 'bold',
556
585
  color: '#666',
557
586
  },
587
+ dataContentWrapper: {
588
+ flex: 1,
589
+ },
558
590
  dataContent: {
591
+ flex: 1,
559
592
  backgroundColor: '#f8f9fa',
560
593
  padding: 10,
561
594
  borderRadius: 4,
@@ -577,6 +610,7 @@ const styles = StyleSheet.create({
577
610
  fontWeight: 'bold',
578
611
  },
579
612
  codeBlock: {
613
+ flex: 1,
580
614
  backgroundColor: '#f8f9fa',
581
615
  padding: 10,
582
616
  borderRadius: 4,
@@ -657,9 +691,13 @@ const styles = StyleSheet.create({
657
691
  color: '#666',
658
692
  },
659
693
  longTextContainer: {
660
- maxHeight: 200,
694
+ flex: 1,
661
695
  paddingHorizontal: 8,
662
696
  paddingVertical: 5,
697
+ backgroundColor: '#f8f9fa',
698
+ },
699
+ longTextContent: {
700
+ paddingBottom: 10,
663
701
  },
664
702
  })
665
703
 
@@ -5,7 +5,6 @@ import {
5
5
  StyleSheet,
6
6
  FlatList,
7
7
  TouchableOpacity,
8
- Modal,
9
8
  } from 'react-native'
10
9
  import HttpLogDetails from './HttpLogDetails'
11
10
 
@@ -76,6 +75,44 @@ const SubViewHTTPLogs = ({ logs = [] }) => {
76
75
  )
77
76
  }
78
77
 
78
+ // If a log is selected, show the details view with a back button
79
+ if (selectedLog) {
80
+ return (
81
+ <View style={styles.container}>
82
+ <View style={styles.detailsHeader}>
83
+ <TouchableOpacity
84
+ style={styles.backButton}
85
+ onPress={() => setSelectedLog(null)}>
86
+ <Text style={styles.backButtonText}>← Back</Text>
87
+ </TouchableOpacity>
88
+ <View style={styles.headerMethodStatus}>
89
+ <Text
90
+ style={[
91
+ styles.headerMethod,
92
+ { color: getMethodColor(selectedLog.request?.method) },
93
+ ]}>
94
+ {(selectedLog.request?.method || 'GET').toUpperCase()}
95
+ </Text>
96
+ <Text
97
+ style={[
98
+ styles.headerStatus,
99
+ {
100
+ color:
101
+ selectedLog.response?.status >= 400
102
+ ? '#ff4444'
103
+ : '#00C851',
104
+ },
105
+ ]}>
106
+ {selectedLog.response?.status || 'Error'}
107
+ </Text>
108
+ </View>
109
+ </View>
110
+ <HttpLogDetails log={selectedLog} />
111
+ </View>
112
+ )
113
+ }
114
+
115
+ // Otherwise show the list view
79
116
  return (
80
117
  <View style={styles.container}>
81
118
  {logs.length === 0 ? (
@@ -88,56 +125,6 @@ const SubViewHTTPLogs = ({ logs = [] }) => {
88
125
  style={styles.list}
89
126
  />
90
127
  )}
91
-
92
- <Modal
93
- visible={!!selectedLog}
94
- animationType='slide'
95
- transparent={true}
96
- onRequestClose={() => setSelectedLog(null)}>
97
- {selectedLog && (
98
- <TouchableOpacity
99
- style={styles.modalContainer}
100
- activeOpacity={1}
101
- onPress={() => setSelectedLog(null)}>
102
- <TouchableOpacity
103
- style={styles.modalContent}
104
- activeOpacity={1}
105
- onPress={(e) => e.stopPropagation()}>
106
- <View style={styles.modalHeader}>
107
- <View style={styles.modalHeaderContent}>
108
- <View style={styles.modalMethodStatus}>
109
- <Text
110
- style={[
111
- styles.modalMethod,
112
- { color: getMethodColor(selectedLog.request?.method) },
113
- ]}>
114
- {(selectedLog.request?.method || 'GET').toUpperCase()}
115
- </Text>
116
- <Text
117
- style={[
118
- styles.modalStatus,
119
- {
120
- color:
121
- selectedLog.response?.status >= 400
122
- ? '#ff4444'
123
- : '#00C851',
124
- },
125
- ]}>
126
- {selectedLog.response?.status || 'Error'}
127
- </Text>
128
- </View>
129
- </View>
130
- <TouchableOpacity
131
- style={styles.closeButton}
132
- onPress={() => setSelectedLog(null)}>
133
- <Text style={styles.closeButtonText}>×</Text>
134
- </TouchableOpacity>
135
- </View>
136
- <HttpLogDetails log={selectedLog} />
137
- </TouchableOpacity>
138
- </TouchableOpacity>
139
- )}
140
- </Modal>
141
128
  </View>
142
129
  )
143
130
  }
@@ -211,20 +198,7 @@ const styles = StyleSheet.create({
211
198
  fontSize: 12,
212
199
  marginLeft: 8,
213
200
  },
214
- modalContainer: {
215
- flex: 1,
216
- backgroundColor: 'rgba(0,0,0,0.5)',
217
- justifyContent: 'flex-end',
218
- alignItems: 'center',
219
- },
220
- modalContent: {
221
- width: '100%',
222
- height: '90%',
223
- backgroundColor: '#fff',
224
- borderRadius: 10,
225
- overflow: 'hidden',
226
- },
227
- modalHeader: {
201
+ detailsHeader: {
228
202
  flexDirection: 'row',
229
203
  alignItems: 'center',
230
204
  padding: 15,
@@ -232,36 +206,30 @@ const styles = StyleSheet.create({
232
206
  borderBottomColor: '#eee',
233
207
  backgroundColor: '#f8f9fa',
234
208
  },
235
- modalHeaderContent: {
236
- flex: 1,
209
+ backButton: {
210
+ paddingHorizontal: 10,
211
+ paddingVertical: 5,
212
+ borderRadius: 4,
213
+ backgroundColor: '#eee',
237
214
  marginRight: 10,
238
215
  },
239
- modalMethodStatus: {
216
+ backButtonText: {
217
+ color: '#333',
218
+ fontWeight: '500',
219
+ },
220
+ headerMethodStatus: {
240
221
  flexDirection: 'row',
241
222
  alignItems: 'center',
242
223
  },
243
- modalMethod: {
224
+ headerMethod: {
244
225
  fontSize: 16,
245
226
  fontWeight: 'bold',
246
227
  marginRight: 10,
247
228
  },
248
- modalStatus: {
229
+ headerStatus: {
249
230
  fontSize: 14,
250
231
  fontWeight: '600',
251
232
  },
252
- closeButton: {
253
- width: 30,
254
- height: 30,
255
- alignItems: 'center',
256
- justifyContent: 'center',
257
- borderRadius: 15,
258
- backgroundColor: '#eee',
259
- },
260
- closeButtonText: {
261
- fontSize: 20,
262
- color: '#666',
263
- lineHeight: 20,
264
- },
265
233
  })
266
234
 
267
235
  export default SubViewHTTPLogs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-debug-toolkit",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "A simple yet powerful debugging toolkit for React Native with a convenient floating UI for development",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",