react-native-xenon 0.4.0 → 0.5.0

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.
Files changed (156) hide show
  1. package/LICENSE +1 -1
  2. package/lib/commonjs/assets/icons/arrow-left.png +0 -0
  3. package/lib/commonjs/assets/icons/beautify.png +0 -0
  4. package/lib/commonjs/assets/icons/share.png +0 -0
  5. package/lib/commonjs/core/utils.js +49 -14
  6. package/lib/commonjs/core/utils.js.map +1 -1
  7. package/lib/commonjs/hooks/useNetworkInterceptor.js +5 -4
  8. package/lib/commonjs/hooks/useNetworkInterceptor.js.map +1 -1
  9. package/lib/commonjs/interceptors/FetchInterceptor.js +1 -1
  10. package/lib/commonjs/interceptors/FetchInterceptor.js.map +1 -1
  11. package/lib/commonjs/theme/colors.js +1 -0
  12. package/lib/commonjs/theme/colors.js.map +1 -1
  13. package/lib/commonjs/theme/icons.js +4 -1
  14. package/lib/commonjs/theme/icons.js.map +1 -1
  15. package/lib/commonjs/types/common.js.map +1 -1
  16. package/lib/commonjs/ui/Xenon.js +92 -110
  17. package/lib/commonjs/ui/Xenon.js.map +1 -1
  18. package/lib/commonjs/ui/components/details/DetailsViewer.js +11 -7
  19. package/lib/commonjs/ui/components/details/DetailsViewer.js.map +1 -1
  20. package/lib/commonjs/ui/components/details/NetworkRequestDetails.js +55 -60
  21. package/lib/commonjs/ui/components/details/NetworkRequestDetails.js.map +1 -1
  22. package/lib/commonjs/ui/components/headers/DebuggerHeader.js +139 -73
  23. package/lib/commonjs/ui/components/headers/DebuggerHeader.js.map +1 -1
  24. package/lib/commonjs/ui/components/headers/NetworkPanelHeader.js +3 -3
  25. package/lib/commonjs/ui/components/headers/NetworkPanelHeader.js.map +1 -1
  26. package/lib/commonjs/ui/components/items/DebuggerHeaderItem.js +4 -4
  27. package/lib/commonjs/ui/components/items/DebuggerHeaderItem.js.map +1 -1
  28. package/lib/commonjs/ui/components/items/NetworkPanelItem.js +4 -4
  29. package/lib/commonjs/ui/components/items/NetworkPanelItem.js.map +1 -1
  30. package/lib/commonjs/ui/components/panels/ConsolePanel.js +9 -6
  31. package/lib/commonjs/ui/components/panels/ConsolePanel.js.map +1 -1
  32. package/lib/commonjs/ui/components/panels/NetworkPanel.js +6 -4
  33. package/lib/commonjs/ui/components/panels/NetworkPanel.js.map +1 -1
  34. package/lib/module/assets/icons/arrow-left.png +0 -0
  35. package/lib/module/assets/icons/beautify.png +0 -0
  36. package/lib/module/assets/icons/share.png +0 -0
  37. package/lib/module/core/utils.js +49 -14
  38. package/lib/module/core/utils.js.map +1 -1
  39. package/lib/module/hooks/useNetworkInterceptor.js +5 -4
  40. package/lib/module/hooks/useNetworkInterceptor.js.map +1 -1
  41. package/lib/module/interceptors/FetchInterceptor.js +1 -1
  42. package/lib/module/interceptors/FetchInterceptor.js.map +1 -1
  43. package/lib/module/theme/colors.js +1 -0
  44. package/lib/module/theme/colors.js.map +1 -1
  45. package/lib/module/theme/icons.js +4 -1
  46. package/lib/module/theme/icons.js.map +1 -1
  47. package/lib/module/types/common.js.map +1 -1
  48. package/lib/module/ui/Xenon.js +92 -110
  49. package/lib/module/ui/Xenon.js.map +1 -1
  50. package/lib/module/ui/components/details/DetailsViewer.js +11 -7
  51. package/lib/module/ui/components/details/DetailsViewer.js.map +1 -1
  52. package/lib/module/ui/components/details/NetworkRequestDetails.js +55 -60
  53. package/lib/module/ui/components/details/NetworkRequestDetails.js.map +1 -1
  54. package/lib/module/ui/components/headers/DebuggerHeader.js +139 -73
  55. package/lib/module/ui/components/headers/DebuggerHeader.js.map +1 -1
  56. package/lib/module/ui/components/headers/NetworkPanelHeader.js +3 -3
  57. package/lib/module/ui/components/headers/NetworkPanelHeader.js.map +1 -1
  58. package/lib/module/ui/components/items/DebuggerHeaderItem.js +4 -4
  59. package/lib/module/ui/components/items/DebuggerHeaderItem.js.map +1 -1
  60. package/lib/module/ui/components/items/NetworkPanelItem.js +4 -4
  61. package/lib/module/ui/components/items/NetworkPanelItem.js.map +1 -1
  62. package/lib/module/ui/components/panels/ConsolePanel.js +9 -6
  63. package/lib/module/ui/components/panels/ConsolePanel.js.map +1 -1
  64. package/lib/module/ui/components/panels/NetworkPanel.js +6 -4
  65. package/lib/module/ui/components/panels/NetworkPanel.js.map +1 -1
  66. package/lib/typescript/commonjs/src/contexts/MainContext.d.ts +1 -1
  67. package/lib/typescript/commonjs/src/contexts/MainContext.d.ts.map +1 -1
  68. package/lib/typescript/commonjs/src/core/utils.d.ts +14 -4
  69. package/lib/typescript/commonjs/src/core/utils.d.ts.map +1 -1
  70. package/lib/typescript/commonjs/src/hooks/useNetworkInterceptor.d.ts.map +1 -1
  71. package/lib/typescript/commonjs/src/interceptors/FetchInterceptor.d.ts.map +1 -1
  72. package/lib/typescript/commonjs/src/theme/colors.d.ts +1 -0
  73. package/lib/typescript/commonjs/src/theme/colors.d.ts.map +1 -1
  74. package/lib/typescript/commonjs/src/theme/icons.d.ts +3 -0
  75. package/lib/typescript/commonjs/src/theme/icons.d.ts.map +1 -1
  76. package/lib/typescript/commonjs/src/types/common.d.ts +13 -1
  77. package/lib/typescript/commonjs/src/types/common.d.ts.map +1 -1
  78. package/lib/typescript/commonjs/src/ui/Xenon.d.ts +12 -15
  79. package/lib/typescript/commonjs/src/ui/Xenon.d.ts.map +1 -1
  80. package/lib/typescript/commonjs/src/ui/components/details/DetailsViewer.d.ts.map +1 -1
  81. package/lib/typescript/commonjs/src/ui/components/details/NetworkRequestDetails.d.ts.map +1 -1
  82. package/lib/typescript/commonjs/src/ui/components/headers/DebuggerHeader.d.ts +1 -5
  83. package/lib/typescript/commonjs/src/ui/components/headers/DebuggerHeader.d.ts.map +1 -1
  84. package/lib/typescript/commonjs/src/ui/components/items/DebuggerHeaderItem.d.ts +2 -1
  85. package/lib/typescript/commonjs/src/ui/components/items/DebuggerHeaderItem.d.ts.map +1 -1
  86. package/lib/typescript/commonjs/src/ui/components/panels/ConsolePanel.d.ts.map +1 -1
  87. package/lib/typescript/commonjs/src/ui/components/panels/NetworkPanel.d.ts.map +1 -1
  88. package/lib/typescript/module/src/contexts/MainContext.d.ts +1 -1
  89. package/lib/typescript/module/src/contexts/MainContext.d.ts.map +1 -1
  90. package/lib/typescript/module/src/core/utils.d.ts +14 -4
  91. package/lib/typescript/module/src/core/utils.d.ts.map +1 -1
  92. package/lib/typescript/module/src/hooks/useNetworkInterceptor.d.ts.map +1 -1
  93. package/lib/typescript/module/src/interceptors/FetchInterceptor.d.ts.map +1 -1
  94. package/lib/typescript/module/src/theme/colors.d.ts +1 -0
  95. package/lib/typescript/module/src/theme/colors.d.ts.map +1 -1
  96. package/lib/typescript/module/src/theme/icons.d.ts +3 -0
  97. package/lib/typescript/module/src/theme/icons.d.ts.map +1 -1
  98. package/lib/typescript/module/src/types/common.d.ts +13 -1
  99. package/lib/typescript/module/src/types/common.d.ts.map +1 -1
  100. package/lib/typescript/module/src/ui/Xenon.d.ts +12 -15
  101. package/lib/typescript/module/src/ui/Xenon.d.ts.map +1 -1
  102. package/lib/typescript/module/src/ui/components/details/DetailsViewer.d.ts.map +1 -1
  103. package/lib/typescript/module/src/ui/components/details/NetworkRequestDetails.d.ts.map +1 -1
  104. package/lib/typescript/module/src/ui/components/headers/DebuggerHeader.d.ts +1 -5
  105. package/lib/typescript/module/src/ui/components/headers/DebuggerHeader.d.ts.map +1 -1
  106. package/lib/typescript/module/src/ui/components/items/DebuggerHeaderItem.d.ts +2 -1
  107. package/lib/typescript/module/src/ui/components/items/DebuggerHeaderItem.d.ts.map +1 -1
  108. package/lib/typescript/module/src/ui/components/panels/ConsolePanel.d.ts.map +1 -1
  109. package/lib/typescript/module/src/ui/components/panels/NetworkPanel.d.ts.map +1 -1
  110. package/package.json +1 -1
  111. package/src/assets/icons/arrow-left.png +0 -0
  112. package/src/assets/icons/beautify.png +0 -0
  113. package/src/assets/icons/share.png +0 -0
  114. package/src/contexts/MainContext.ts +1 -1
  115. package/src/core/utils.ts +56 -17
  116. package/src/hooks/useNetworkInterceptor.ts +17 -4
  117. package/src/interceptors/FetchInterceptor.ts +5 -1
  118. package/src/theme/colors.ts +1 -0
  119. package/src/theme/icons.ts +3 -0
  120. package/src/types/common.ts +17 -1
  121. package/src/ui/Xenon.tsx +78 -107
  122. package/src/ui/components/details/DetailsViewer.tsx +9 -7
  123. package/src/ui/components/details/NetworkRequestDetails.tsx +87 -74
  124. package/src/ui/components/headers/DebuggerHeader.tsx +199 -91
  125. package/src/ui/components/headers/NetworkPanelHeader.tsx +3 -3
  126. package/src/ui/components/items/DebuggerHeaderItem.tsx +3 -4
  127. package/src/ui/components/items/NetworkPanelItem.tsx +4 -4
  128. package/src/ui/components/panels/ConsolePanel.tsx +9 -5
  129. package/src/ui/components/panels/NetworkPanel.tsx +13 -3
  130. package/lib/commonjs/core/data.js +0 -10
  131. package/lib/commonjs/core/data.js.map +0 -1
  132. package/lib/commonjs/ui/components/headers/NetworkRequestDetailsHeader.js +0 -64
  133. package/lib/commonjs/ui/components/headers/NetworkRequestDetailsHeader.js.map +0 -1
  134. package/lib/commonjs/ui/components/items/NetworkRequestDetailsHeaderItem.js +0 -48
  135. package/lib/commonjs/ui/components/items/NetworkRequestDetailsHeaderItem.js.map +0 -1
  136. package/lib/module/core/data.js +0 -10
  137. package/lib/module/core/data.js.map +0 -1
  138. package/lib/module/ui/components/headers/NetworkRequestDetailsHeader.js +0 -64
  139. package/lib/module/ui/components/headers/NetworkRequestDetailsHeader.js.map +0 -1
  140. package/lib/module/ui/components/items/NetworkRequestDetailsHeaderItem.js +0 -48
  141. package/lib/module/ui/components/items/NetworkRequestDetailsHeaderItem.js.map +0 -1
  142. package/lib/typescript/commonjs/src/core/data.d.ts +0 -10
  143. package/lib/typescript/commonjs/src/core/data.d.ts.map +0 -1
  144. package/lib/typescript/commonjs/src/ui/components/headers/NetworkRequestDetailsHeader.d.ts +0 -13
  145. package/lib/typescript/commonjs/src/ui/components/headers/NetworkRequestDetailsHeader.d.ts.map +0 -1
  146. package/lib/typescript/commonjs/src/ui/components/items/NetworkRequestDetailsHeaderItem.d.ts +0 -9
  147. package/lib/typescript/commonjs/src/ui/components/items/NetworkRequestDetailsHeaderItem.d.ts.map +0 -1
  148. package/lib/typescript/module/src/core/data.d.ts +0 -10
  149. package/lib/typescript/module/src/core/data.d.ts.map +0 -1
  150. package/lib/typescript/module/src/ui/components/headers/NetworkRequestDetailsHeader.d.ts +0 -13
  151. package/lib/typescript/module/src/ui/components/headers/NetworkRequestDetailsHeader.d.ts.map +0 -1
  152. package/lib/typescript/module/src/ui/components/items/NetworkRequestDetailsHeaderItem.d.ts +0 -9
  153. package/lib/typescript/module/src/ui/components/items/NetworkRequestDetailsHeaderItem.d.ts.map +0 -1
  154. package/src/core/data.ts +0 -12
  155. package/src/ui/components/headers/NetworkRequestDetailsHeader.tsx +0 -90
  156. package/src/ui/components/items/NetworkRequestDetailsHeaderItem.tsx +0 -49
@@ -1,3 +1,5 @@
1
+ import type { HttpRequest, LogMessage, WebSocketRequest } from '.';
2
+
1
3
  export enum NetworkType {
2
4
  XHR = 'xhr',
3
5
  Fetch = 'fetch',
@@ -19,10 +21,24 @@ export interface NetworkRequest {
19
21
  duration?: number;
20
22
  }
21
23
 
22
- export type NetworkTab = 'headers' | 'queryStringParameters' | 'body' | 'response' | 'messages';
24
+ export type DetailTab = 'overview' | 'headers' | 'request' | 'response' | 'messages' | 'logMessage';
23
25
 
24
26
  export interface DebuggerState {
25
27
  visibility: 'hidden' | 'bubble' | 'panel';
26
28
  position: 'top' | 'bottom';
27
29
  selectedPanel: DebuggerPanel | null;
30
+ detailsData:
31
+ | {
32
+ type: DebuggerPanel.Network;
33
+ data: HttpRequest | WebSocketRequest;
34
+ selectedTab: Exclude<DetailTab, 'logMessage'>;
35
+ beautified: boolean;
36
+ }
37
+ | {
38
+ type: DebuggerPanel.Console;
39
+ data: LogMessage;
40
+ selectedTab: Extract<DetailTab, 'logMessage'>;
41
+ beautified: boolean;
42
+ }
43
+ | null;
28
44
  }
package/src/ui/Xenon.tsx CHANGED
@@ -1,51 +1,53 @@
1
1
  import { enableMapSet } from 'immer';
2
- import {
3
- createRef,
4
- memo,
5
- useImperativeHandle,
6
- useMemo,
7
- useRef,
8
- type NamedExoticComponent,
9
- } from 'react';
2
+ import { createRef, memo, useImperativeHandle, useMemo, useRef } from 'react';
10
3
  import { Animated, StyleSheet, useWindowDimensions } from 'react-native';
11
4
  import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
12
5
  import { useImmer } from 'use-immer';
13
6
  import MainContext from '../contexts/MainContext';
14
- import { detailsData } from '../core/data';
15
7
  import { getVerticalSafeMargin } from '../core/utils';
16
8
  import { useConsoleInterceptor, useNetworkInterceptor } from '../hooks';
17
9
  import colors from '../theme/colors';
18
10
  import { DebuggerPanel, type DebuggerState } from '../types';
19
11
  import { Bubble, ConsolePanel, DebuggerHeader, DetailsViewer, NetworkPanel } from './components';
20
12
 
21
- interface XenonComponentMethods {
22
- isVisible(): boolean;
23
- show(): void;
24
- hide(): void;
25
- }
26
-
27
- interface XenonComponentProps {
28
- autoInspectNetworkEnabled?: boolean;
29
- autoInspectConsoleEnabled?: boolean;
30
- bubbleSize?: number;
31
- idleBubbleOpacity?: number;
32
- }
33
-
34
- interface ReactNativeXenon extends XenonComponentMethods {
35
- Component: NamedExoticComponent<XenonComponentProps>;
36
- }
37
-
38
- enableMapSet();
39
-
40
- const rootRef = createRef<XenonComponentMethods>();
41
-
42
- const XenonComponent = memo<XenonComponentProps>(
43
- ({
13
+ namespace Xenon {
14
+ interface Methods {
15
+ isVisible(): boolean;
16
+ show(): void;
17
+ hide(): void;
18
+ }
19
+
20
+ interface Props {
21
+ autoInspectNetworkEnabled?: boolean;
22
+ autoInspectConsoleEnabled?: boolean;
23
+ bubbleSize?: number;
24
+ idleBubbleOpacity?: number;
25
+ }
26
+
27
+ enableMapSet();
28
+
29
+ const ref = createRef<Methods>();
30
+
31
+ const styles = StyleSheet.create({
32
+ container: {
33
+ flex: 1,
34
+ ...StyleSheet.absoluteFillObject,
35
+ top: undefined,
36
+ bottom: undefined,
37
+ zIndex: 9999,
38
+ backgroundColor: colors.lightGray,
39
+ },
40
+ safeArea: {
41
+ flex: 1,
42
+ },
43
+ });
44
+
45
+ const Debugger = ({
44
46
  autoInspectNetworkEnabled = true,
45
47
  autoInspectConsoleEnabled = true,
46
48
  bubbleSize = 40,
47
49
  idleBubbleOpacity = 0.5,
48
- }) => {
50
+ }: Props) => {
49
51
  const { width, height } = useWindowDimensions();
50
52
  const pan = useRef(new Animated.ValueXY({ x: 0, y: getVerticalSafeMargin(height) }));
51
53
 
@@ -53,22 +55,31 @@ const XenonComponent = memo<XenonComponentProps>(
53
55
  visibility: 'hidden',
54
56
  position: 'bottom',
55
57
  selectedPanel: DebuggerPanel.Network,
58
+ detailsData: null,
56
59
  });
57
60
 
58
61
  const detailsShown = useMemo(
59
- () => !debuggerState.selectedPanel && !!detailsData.value,
60
- [debuggerState.selectedPanel],
62
+ () => !debuggerState.selectedPanel && !!debuggerState.detailsData,
63
+ [debuggerState.detailsData, debuggerState.selectedPanel],
64
+ );
65
+
66
+ const containerStyle = useMemo(
67
+ () => [
68
+ styles.container,
69
+ { [debuggerState.position]: 0, height: Math.min(width, height) * 0.75 },
70
+ ],
71
+ [debuggerState.position, height, width],
61
72
  );
62
73
 
63
74
  const networkInterceptor = useNetworkInterceptor({
64
75
  autoEnabled: autoInspectNetworkEnabled,
65
76
  });
66
77
 
67
- const logInterceptor = useConsoleInterceptor({
78
+ const consoleInterceptor = useConsoleInterceptor({
68
79
  autoEnabled: autoInspectConsoleEnabled,
69
80
  });
70
81
 
71
- useImperativeHandle(rootRef, () => {
82
+ useImperativeHandle(ref, () => {
72
83
  const changeVisibility = (condition: boolean, value: DebuggerState['visibility']) => {
73
84
  if (!condition) return;
74
85
 
@@ -90,80 +101,40 @@ const XenonComponent = memo<XenonComponentProps>(
90
101
  };
91
102
  }, [debuggerState.visibility, setDebuggerState]);
92
103
 
93
- const renderContent = () => {
94
- switch (debuggerState.visibility) {
95
- case 'bubble':
96
- return (
97
- <Bubble
98
- bubbleSize={bubbleSize}
99
- idleBubbleOpacity={idleBubbleOpacity}
100
- pan={pan}
101
- screenWidth={width}
102
- screenHeight={height}
103
- />
104
- );
105
- case 'panel':
106
- return (
107
- <SafeAreaProvider
108
- style={[
109
- styles.container,
110
- // eslint-disable-next-line react-native/no-inline-styles
111
- {
112
- [debuggerState.position]: 0,
113
- height: Math.min(width, height) * 0.75,
114
- },
115
- ]}
116
- >
117
- <SafeAreaView style={styles.safeArea}>
118
- <DebuggerHeader detailsShown={detailsShown} />
119
- {debuggerState.selectedPanel === DebuggerPanel.Network && <NetworkPanel />}
120
- {debuggerState.selectedPanel === DebuggerPanel.Console && <ConsolePanel />}
121
- {detailsShown && <DetailsViewer />}
122
- </SafeAreaView>
123
- </SafeAreaProvider>
124
- );
125
- default:
126
- return null;
127
- }
128
- };
129
-
130
104
  return (
131
105
  <MainContext.Provider
132
- value={{ debuggerState, setDebuggerState, networkInterceptor, logInterceptor }}
106
+ value={{ debuggerState, setDebuggerState, networkInterceptor, consoleInterceptor }}
133
107
  >
134
- {renderContent()}
108
+ {debuggerState.visibility === 'bubble' && (
109
+ <Bubble
110
+ bubbleSize={bubbleSize}
111
+ idleBubbleOpacity={idleBubbleOpacity}
112
+ pan={pan}
113
+ screenWidth={width}
114
+ screenHeight={height}
115
+ />
116
+ )}
117
+
118
+ {debuggerState.visibility === 'panel' && (
119
+ <SafeAreaProvider style={containerStyle}>
120
+ <SafeAreaView style={styles.safeArea}>
121
+ <DebuggerHeader />
122
+ {debuggerState.selectedPanel === DebuggerPanel.Network && <NetworkPanel />}
123
+ {debuggerState.selectedPanel === DebuggerPanel.Console && <ConsolePanel />}
124
+ {detailsShown && <DetailsViewer />}
125
+ </SafeAreaView>
126
+ </SafeAreaProvider>
127
+ )}
135
128
  </MainContext.Provider>
136
129
  );
137
- },
138
- );
139
-
140
- const styles = StyleSheet.create({
141
- container: {
142
- flex: 1,
143
- ...StyleSheet.absoluteFillObject,
144
- top: undefined,
145
- bottom: undefined,
146
- zIndex: 9999,
147
- backgroundColor: colors.lightGray,
148
- },
149
- safeArea: {
150
- flex: 1,
151
- },
152
- });
153
-
154
- XenonComponent.displayName = 'Xenon';
155
-
156
- const Xenon: ReactNativeXenon = {
157
- isVisible() {
158
- return rootRef.current?.isVisible() ?? false;
159
- },
160
- show() {
161
- rootRef.current?.show();
162
- },
163
- hide() {
164
- rootRef.current?.hide();
165
- },
166
- Component: XenonComponent,
167
- };
130
+ };
131
+
132
+ export const isVisible = () => ref.current?.isVisible() ?? false;
133
+ export const show = (): void => ref.current?.show();
134
+ export const hide = (): void => ref.current?.hide();
135
+
136
+ export const Component = memo(Debugger);
137
+ Component.displayName = 'Xenon';
138
+ }
168
139
 
169
140
  export default Xenon;
@@ -1,16 +1,18 @@
1
- import { detailsData } from '../../../core/data';
1
+ import { useContext } from 'react';
2
+ import { MainContext } from '../../../contexts';
2
3
  import { DebuggerPanel } from '../../../types';
3
4
  import LogMessageDetails from './LogMessageDetails';
4
5
  import NetworkRequestDetails from './NetworkRequestDetails';
5
6
 
6
7
  export default function DetailsViewer() {
7
- if (!detailsData.value) return null;
8
+ const { debuggerState } = useContext(MainContext)!;
9
+ const detailsData = debuggerState.detailsData;
8
10
 
9
- switch (true) {
10
- case DebuggerPanel.Network in detailsData.value:
11
- return <NetworkRequestDetails item={detailsData.value.network} />;
12
- case DebuggerPanel.Console in detailsData.value:
13
- return <LogMessageDetails item={detailsData.value.console} />;
11
+ switch (detailsData?.type) {
12
+ case DebuggerPanel.Network:
13
+ return <NetworkRequestDetails item={detailsData.data} />;
14
+ case DebuggerPanel.Console:
15
+ return <LogMessageDetails item={detailsData.data} />;
14
16
  default:
15
17
  return null;
16
18
  }
@@ -1,21 +1,17 @@
1
- import { useRef, useState, type JSX, type ReactNode } from 'react';
2
- import { ScrollView, Share, StyleSheet, TouchableOpacity } from 'react-native';
3
- import { URL } from 'react-native-url-polyfill';
4
- import colors from '../../../theme/colors';
5
- import {
6
- NetworkType,
7
- type HttpRequest,
8
- type NetworkTab,
9
- type WebSocketRequest,
10
- } from '../../../types';
1
+ import { useContext, useRef, type JSX, type ReactNode } from 'react';
2
+ import { ScrollView, StyleSheet } from 'react-native';
3
+ import { MainContext } from '../../../contexts';
11
4
  import {
12
- convertToCurl,
5
+ beautify,
13
6
  formatRequestDuration,
14
7
  formatRequestMethod,
15
8
  formatRequestStatusCode,
9
+ getNetworkUtils,
10
+ keyValueToString,
16
11
  limitChar,
17
12
  } from '../../../core/utils';
18
- import NetworkDetailsHeader from '../headers/NetworkRequestDetailsHeader';
13
+ import colors from '../../../theme/colors';
14
+ import { type DetailTab, type HttpRequest, type WebSocketRequest } from '../../../types';
19
15
  import NetworkRequestDetailsItem from '../items/NetworkRequestDetailsItem';
20
16
 
21
17
  interface NetworkRequestDetailsProps {
@@ -23,28 +19,33 @@ interface NetworkRequestDetailsProps {
23
19
  }
24
20
 
25
21
  export default function NetworkRequestDetails({ item }: NetworkRequestDetailsProps) {
26
- const [selectedTab, setSelectedTab] = useState<NetworkTab>('headers');
27
-
28
- const isWebSocket = item.type === NetworkType.WS;
29
-
30
- const requestUrl = new URL(item.url);
31
-
32
- const headerShown = !!item.url;
33
- const queryStringParametersShown = !!requestUrl.search;
34
- const bodyShown = !isWebSocket && !!item.body;
35
- const responseShown = !isWebSocket && !!item.response;
36
- const messagesShown = isWebSocket && !!item.messages;
37
-
38
- const content = useRef<Record<NetworkTab, JSX.Element | null>>({
22
+ const {
23
+ debuggerState: { detailsData },
24
+ } = useContext(MainContext)!;
25
+
26
+ const beautified = useRef<boolean | null>(null);
27
+ const shouldBeautifiedRefUpdate = beautified.current !== detailsData?.beautified;
28
+
29
+ const {
30
+ isHttp,
31
+ requestUrl,
32
+ overviewShown,
33
+ headersShown,
34
+ requestShown,
35
+ responseShown,
36
+ messagesShown,
37
+ } = getNetworkUtils(item);
38
+
39
+ const content = useRef<Record<Exclude<DetailTab, 'logMessage'>, JSX.Element | null>>({
40
+ overview: null,
39
41
  headers: null,
40
- queryStringParameters: null,
41
- body: null,
42
+ request: null,
42
43
  response: null,
43
44
  messages: null,
44
45
  });
45
46
 
46
- if (headerShown && !content.current.headers) {
47
- content.current.headers = (
47
+ if (overviewShown && !content.current.overview) {
48
+ content.current.overview = (
48
49
  <>
49
50
  <NetworkRequestDetailsItem label="Request Type" content={item.type} />
50
51
 
@@ -52,7 +53,7 @@ export default function NetworkRequestDetails({ item }: NetworkRequestDetailsPro
52
53
 
53
54
  <NetworkRequestDetailsItem
54
55
  label="Request Method"
55
- content={formatRequestMethod(isWebSocket ? undefined : item.method)}
56
+ content={formatRequestMethod(isHttp ? (item as HttpRequest).method : undefined)}
56
57
  />
57
58
 
58
59
  <NetworkRequestDetailsItem
@@ -64,75 +65,87 @@ export default function NetworkRequestDetails({ item }: NetworkRequestDetailsPro
64
65
  label="Status Code"
65
66
  content={formatRequestStatusCode(item.status)}
66
67
  />
68
+ </>
69
+ );
70
+ }
67
71
 
68
- {isWebSocket && (
69
- <NetworkRequestDetailsItem label="Headers" content={limitChar(item.options?.headers)} />
70
- )}
71
-
72
- {!isWebSocket && (
73
- <NetworkRequestDetailsItem label="Response Headers" content={item.responseHeaders} />
72
+ if (headersShown && !content.current.headers) {
73
+ content.current.headers = (
74
+ <>
75
+ {!isHttp && (
76
+ <NetworkRequestDetailsItem
77
+ label="Headers"
78
+ content={limitChar((item as WebSocketRequest).options?.headers)}
79
+ />
74
80
  )}
75
81
 
76
- {!isWebSocket && (
77
- <NetworkRequestDetailsItem label="Request Headers" content={item.requestHeadersString} />
82
+ {isHttp && (
83
+ <NetworkRequestDetailsItem
84
+ label="Request Headers"
85
+ content={(item as HttpRequest).requestHeadersString}
86
+ />
78
87
  )}
79
88
 
80
- {!isWebSocket && (
81
- <TouchableOpacity
82
- activeOpacity={0.8}
83
- onPress={() =>
84
- Share.share({
85
- message: convertToCurl(item.method, item.url, item.requestHeaders, item.body),
86
- })
87
- }
88
- style={styles.buttonContent}
89
- >
90
- <NetworkRequestDetailsItem content="Share as cURL" />
91
- </TouchableOpacity>
89
+ {isHttp && (
90
+ <NetworkRequestDetailsItem
91
+ label="Response Headers"
92
+ content={(item as HttpRequest).responseHeaders}
93
+ />
92
94
  )}
93
95
  </>
94
96
  );
95
97
  }
96
98
 
97
- if (queryStringParametersShown && !content.current.queryStringParameters) {
99
+ if (requestShown && shouldBeautifiedRefUpdate) {
98
100
  const queryStringParameters: ReactNode[] = [];
99
101
 
100
102
  requestUrl.searchParams.forEach((value, name) => {
101
103
  queryStringParameters.push(
102
- <NetworkRequestDetailsItem key={name} label={name} content={value} />,
104
+ <NetworkRequestDetailsItem
105
+ key={keyValueToString(name, value, null)}
106
+ label="Query String"
107
+ content={keyValueToString(name, value, null)}
108
+ />,
103
109
  );
104
110
  });
105
111
 
106
- content.current.queryStringParameters = <>{queryStringParameters}</>;
112
+ content.current.request = (
113
+ <>
114
+ {queryStringParameters}
115
+ <NetworkRequestDetailsItem
116
+ label="Body"
117
+ content={beautify((item as HttpRequest).body, detailsData?.beautified ?? false)}
118
+ />
119
+ </>
120
+ );
107
121
  }
108
122
 
109
- if (bodyShown && !content.current.body) {
110
- content.current.body = <NetworkRequestDetailsItem content={limitChar(item.body)} />;
123
+ if (responseShown && shouldBeautifiedRefUpdate) {
124
+ content.current.response = (
125
+ <NetworkRequestDetailsItem
126
+ label="Response"
127
+ content={beautify((item as HttpRequest).response, detailsData?.beautified ?? false)}
128
+ />
129
+ );
111
130
  }
112
131
 
113
- if (responseShown && !content.current.response) {
114
- content.current.response = <NetworkRequestDetailsItem content={limitChar(item.response)} />;
132
+ if (messagesShown && !content.current.messages) {
133
+ content.current.messages = (
134
+ <NetworkRequestDetailsItem
135
+ label="Messages"
136
+ content={`\n${(item as WebSocketRequest).messages}`}
137
+ />
138
+ );
115
139
  }
116
140
 
117
- if (messagesShown && !content.current.messages) {
118
- content.current.messages = <NetworkRequestDetailsItem content={item.messages} />;
141
+ if (shouldBeautifiedRefUpdate) {
142
+ beautified.current = detailsData?.beautified ?? false;
119
143
  }
120
144
 
121
145
  return (
122
- <>
123
- <NetworkDetailsHeader
124
- selectedTab={selectedTab}
125
- onChangeTab={setSelectedTab}
126
- headersShown={headerShown}
127
- queryStringParametersShown={queryStringParametersShown}
128
- bodyShown={bodyShown}
129
- responseShown={responseShown}
130
- messagesShown={messagesShown}
131
- />
132
- <ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
133
- {content.current[selectedTab]}
134
- </ScrollView>
135
- </>
146
+ <ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
147
+ {content.current[detailsData!.selectedTab as keyof typeof content.current]}
148
+ </ScrollView>
136
149
  );
137
150
  }
138
151
 
@@ -141,7 +154,7 @@ const styles = StyleSheet.create({
141
154
  flex: 1,
142
155
  },
143
156
  contentContainer: {
144
- padding: 8,
157
+ paddingHorizontal: 8,
145
158
  },
146
159
  divider: {
147
160
  height: 1,