react-native-inapp-inspector 2.2.1 → 2.2.3

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 (181) hide show
  1. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  2. package/android/.gradle/8.9/checksums/md5-checksums.bin +0 -0
  3. package/android/.gradle/8.9/checksums/sha1-checksums.bin +0 -0
  4. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  5. package/android/.gradle/8.9/executionHistory/executionHistory.lock +0 -0
  6. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  7. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  8. package/android/.gradle/8.9/gc.properties +0 -0
  9. package/android/.gradle/9.2.0/checksums/checksums.lock +0 -0
  10. package/android/.gradle/9.2.0/fileChanges/last-build.bin +0 -0
  11. package/android/.gradle/9.2.0/fileHashes/fileHashes.bin +0 -0
  12. package/android/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
  13. package/android/.gradle/9.2.0/gc.properties +0 -0
  14. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  15. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  16. package/android/.gradle/vcs-1/gc.properties +0 -0
  17. package/android/build/reports/problems/problems-report.html +659 -0
  18. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +28 -6
  19. package/dist/commonjs/analytics.d.ts +7 -0
  20. package/dist/commonjs/analytics.js +28 -0
  21. package/dist/commonjs/bundle.d.ts +6 -0
  22. package/dist/commonjs/bundle.js +20 -0
  23. package/dist/commonjs/console.d.ts +7 -0
  24. package/dist/commonjs/console.js +20 -0
  25. package/dist/commonjs/constants/version.d.ts +1 -1
  26. package/dist/commonjs/constants/version.js +1 -1
  27. package/dist/commonjs/crash.d.ts +7 -0
  28. package/dist/commonjs/crash.js +27 -0
  29. package/dist/commonjs/customHooks/analyticsLogger.d.ts +3 -0
  30. package/dist/commonjs/customHooks/analyticsLogger.js +23 -2
  31. package/dist/commonjs/customHooks/consoleLogger.d.ts +3 -0
  32. package/dist/commonjs/customHooks/consoleLogger.js +24 -4
  33. package/dist/commonjs/customHooks/crashHandler.d.ts +2 -0
  34. package/dist/commonjs/customHooks/crashHandler.js +15 -1
  35. package/dist/commonjs/customHooks/networkLogger.d.ts +3 -0
  36. package/dist/commonjs/customHooks/networkLogger.js +23 -2
  37. package/dist/commonjs/customHooks/performanceTracker.d.ts +3 -0
  38. package/dist/commonjs/customHooks/performanceTracker.js +34 -3
  39. package/dist/commonjs/customHooks/reduxLogger.d.ts +3 -0
  40. package/dist/commonjs/customHooks/reduxLogger.js +24 -4
  41. package/dist/commonjs/helpers/index.d.ts +1 -0
  42. package/dist/commonjs/helpers/index.js +1 -0
  43. package/dist/commonjs/helpers/memoryManager.d.ts +29 -0
  44. package/dist/commonjs/helpers/memoryManager.js +112 -0
  45. package/dist/commonjs/helpers/telemetry.js +4 -4
  46. package/dist/commonjs/index.d.ts +7 -1
  47. package/dist/commonjs/index.js +36 -2
  48. package/dist/commonjs/network.d.ts +6 -0
  49. package/dist/commonjs/network.js +17 -0
  50. package/dist/commonjs/performance.d.ts +6 -0
  51. package/dist/commonjs/performance.js +33 -0
  52. package/dist/commonjs/redux.d.ts +5 -0
  53. package/dist/commonjs/redux.js +24 -0
  54. package/dist/esm/analytics.d.ts +7 -0
  55. package/dist/esm/analytics.js +6 -0
  56. package/dist/esm/bundle.d.ts +6 -0
  57. package/dist/esm/bundle.js +6 -0
  58. package/dist/esm/console.d.ts +7 -0
  59. package/dist/esm/console.js +6 -0
  60. package/dist/esm/constants/version.d.ts +1 -1
  61. package/dist/esm/constants/version.js +1 -1
  62. package/dist/esm/crash.d.ts +7 -0
  63. package/dist/esm/crash.js +6 -0
  64. package/dist/esm/customHooks/analyticsLogger.d.ts +3 -0
  65. package/dist/esm/customHooks/analyticsLogger.js +19 -1
  66. package/dist/esm/customHooks/consoleLogger.d.ts +3 -0
  67. package/dist/esm/customHooks/consoleLogger.js +20 -3
  68. package/dist/esm/customHooks/crashHandler.d.ts +2 -0
  69. package/dist/esm/customHooks/crashHandler.js +12 -0
  70. package/dist/esm/customHooks/networkLogger.d.ts +3 -0
  71. package/dist/esm/customHooks/networkLogger.js +19 -1
  72. package/dist/esm/customHooks/performanceTracker.d.ts +3 -0
  73. package/dist/esm/customHooks/performanceTracker.js +30 -2
  74. package/dist/esm/customHooks/reduxLogger.d.ts +3 -0
  75. package/dist/esm/customHooks/reduxLogger.js +20 -3
  76. package/dist/esm/helpers/index.d.ts +1 -0
  77. package/dist/esm/helpers/index.js +1 -0
  78. package/dist/esm/helpers/memoryManager.d.ts +29 -0
  79. package/dist/esm/helpers/memoryManager.js +104 -0
  80. package/dist/esm/helpers/telemetry.js +4 -4
  81. package/dist/esm/index.d.ts +7 -1
  82. package/dist/esm/index.js +17 -3
  83. package/dist/esm/network.d.ts +6 -0
  84. package/dist/esm/network.js +5 -0
  85. package/dist/esm/performance.d.ts +6 -0
  86. package/dist/esm/performance.js +6 -0
  87. package/dist/esm/redux.d.ts +5 -0
  88. package/dist/esm/redux.js +5 -0
  89. package/package.json +53 -2
  90. package/src/analytics.ts +35 -0
  91. package/src/bundle.ts +25 -0
  92. package/src/components/AnalyticsDetail.tsx +865 -0
  93. package/src/components/AnalyticsEventCard.tsx +441 -0
  94. package/src/components/AnalyticsGraph.tsx +583 -0
  95. package/src/components/AnimatedEntrance.tsx +64 -0
  96. package/src/components/AppHeaderLogo.tsx +109 -0
  97. package/src/components/BrandCircleIcon.tsx +144 -0
  98. package/src/components/BrandSquareIcon.tsx +144 -0
  99. package/src/components/CodeSnippet.tsx +725 -0
  100. package/src/components/ConsoleLogCard.tsx +628 -0
  101. package/src/components/CopyButton.tsx +87 -0
  102. package/src/components/DiffViewer.tsx +82 -0
  103. package/src/components/DomainHeader.tsx +237 -0
  104. package/src/components/EmptyState.tsx +73 -0
  105. package/src/components/EndOfListFooter.tsx +100 -0
  106. package/src/components/ErrorBoundary.tsx +688 -0
  107. package/src/components/HeadersSection.tsx +192 -0
  108. package/src/components/HighlightText.tsx +100 -0
  109. package/src/components/Inspector/AnalyticsFilterModal.tsx +1250 -0
  110. package/src/components/Inspector/AnalyticsTab.tsx +1336 -0
  111. package/src/components/Inspector/BundleTab.tsx +4731 -0
  112. package/src/components/Inspector/ConsoleTab.tsx +702 -0
  113. package/src/components/Inspector/CrashDetail.tsx +941 -0
  114. package/src/components/Inspector/CrashFilterModal.tsx +721 -0
  115. package/src/components/Inspector/CrashTab.tsx +871 -0
  116. package/src/components/Inspector/FabLauncher.tsx +80 -0
  117. package/src/components/Inspector/InspectorContext.tsx +28 -0
  118. package/src/components/Inspector/InspectorHeader.tsx +973 -0
  119. package/src/components/Inspector/LogDetail.tsx +1427 -0
  120. package/src/components/Inspector/MainScreen.tsx +258 -0
  121. package/src/components/Inspector/NavigationTracker.tsx +13 -0
  122. package/src/components/Inspector/NetworkDetail.tsx +794 -0
  123. package/src/components/Inspector/NetworkTab.tsx +1095 -0
  124. package/src/components/Inspector/NpmUpdateToast.tsx +392 -0
  125. package/src/components/Inspector/PerformanceTab.tsx +1894 -0
  126. package/src/components/Inspector/ReduxDetail.tsx +1651 -0
  127. package/src/components/Inspector/ReduxTab.tsx +954 -0
  128. package/src/components/Inspector/SettingsPanel.tsx +3181 -0
  129. package/src/components/Inspector/TabBar.tsx +187 -0
  130. package/src/components/Inspector/TelemetryConsentModal.tsx +392 -0
  131. package/src/components/Inspector/UpdateAvailableModal.tsx +545 -0
  132. package/src/components/JsonViewer.tsx +486 -0
  133. package/src/components/LogCard.tsx +491 -0
  134. package/src/components/LogSyntaxHighlighter.tsx +178 -0
  135. package/src/components/MetaAccordion.tsx +340 -0
  136. package/src/components/MiniBarChart.tsx +42 -0
  137. package/src/components/MiniLineChart.tsx +33 -0
  138. package/src/components/NetworkIcons.tsx +2118 -0
  139. package/src/components/SectionHeader.tsx +113 -0
  140. package/src/components/SegmentedTabs.tsx +83 -0
  141. package/src/components/Slider.tsx +300 -0
  142. package/src/components/SourcePageCard.tsx +148 -0
  143. package/src/components/Toast.tsx +131 -0
  144. package/src/components/TouchableScale.tsx +91 -0
  145. package/src/components/TreeNode.tsx +186 -0
  146. package/src/console.ts +24 -0
  147. package/src/constants/index.ts +38 -0
  148. package/src/constants/version.ts +3 -0
  149. package/src/crash.ts +32 -0
  150. package/src/customHooks/analyticsLogger.ts +336 -0
  151. package/src/customHooks/bundleAnalyzer.ts +1231 -0
  152. package/src/customHooks/consoleLogger.ts +497 -0
  153. package/src/customHooks/crashHandler.ts +944 -0
  154. package/src/customHooks/logFilters.ts +32 -0
  155. package/src/customHooks/networkLogger.ts +419 -0
  156. package/src/customHooks/performanceTracker.ts +1014 -0
  157. package/src/customHooks/reduxLogger.ts +406 -0
  158. package/src/customHooks/useAccordion.tsx +60 -0
  159. package/src/decorators/index.ts +184 -0
  160. package/src/helpers/gaAnalyticsRegistry.ts +204 -0
  161. package/src/helpers/index.ts +860 -0
  162. package/src/helpers/memoryManager.ts +138 -0
  163. package/src/helpers/searchQueryParser.ts +283 -0
  164. package/src/helpers/settingsStore.ts +171 -0
  165. package/src/helpers/telemetry.ts +505 -0
  166. package/src/helpers/toast.ts +17 -0
  167. package/src/i18n/index.ts +69 -0
  168. package/src/i18n/locales/en.json +1052 -0
  169. package/src/index.tsx +2336 -0
  170. package/src/native/NativeInspector.ts +397 -0
  171. package/src/native/NativeNetworkInspector.ts +24 -0
  172. package/src/network.ts +22 -0
  173. package/src/performance.ts +38 -0
  174. package/src/redux.ts +23 -0
  175. package/src/styles/AppColors.ts +408 -0
  176. package/src/styles/AppFonts.ts +8 -0
  177. package/src/styles/common.ts +209 -0
  178. package/src/styles/index.ts +1570 -0
  179. package/src/types/enums.ts +194 -0
  180. package/src/types/index.ts +34 -0
  181. package/src/types/interfaces.ts +515 -0
@@ -0,0 +1,187 @@
1
+ import React from 'react';
2
+ import {Animated, ScrollView, Text, TouchableOpacity, View} from 'react-native';
3
+ import {useInspector} from './InspectorContext';
4
+ import styles from '../../styles';
5
+ import {AppColors} from '../../styles/AppColors';
6
+ import TouchableScale from '../TouchableScale';
7
+ import {
8
+ SignalIcon,
9
+ TerminalIcon,
10
+ AnalyticsIcon,
11
+ PackageIcon,
12
+ ReduxIcon,
13
+ PerformanceIcon,
14
+ CrashIcon,
15
+ } from '../NetworkIcons';
16
+
17
+ import {isReduxConnected} from '../../customHooks/reduxLogger';
18
+ import {isAnalyticsConnected} from '../../customHooks/analyticsLogger';
19
+ import {triggerNativeHaptic} from '../../native/NativeInspector';
20
+
21
+ const TabBar = React.memo(() => {
22
+ const {
23
+ activeTab,
24
+ switchActiveTab,
25
+ tabVisibility,
26
+ logs,
27
+ consoleLogs,
28
+ analyticsEvents,
29
+ crashRecords,
30
+ lastReadApisCount,
31
+ lastReadLogsCount,
32
+ lastReadCrashesCount,
33
+ unreadPulseAnim,
34
+ } = useInspector();
35
+
36
+ const isReduxAvail = isReduxConnected();
37
+ const isAnalyticsAvail = isAnalyticsConnected();
38
+
39
+ return (
40
+ <View style={styles.tabBarContainer}>
41
+ <ScrollView
42
+ horizontal
43
+ showsHorizontalScrollIndicator={false}
44
+ contentContainerStyle={{paddingRight: 16}}>
45
+ {(
46
+ [
47
+ {
48
+ key: 'apis',
49
+ label: 'APIs',
50
+ count: logs.length,
51
+ icon: 'apis',
52
+ },
53
+ {
54
+ key: 'logs',
55
+ label: 'Logs',
56
+ count: consoleLogs.length,
57
+ icon: 'logs',
58
+ },
59
+ {
60
+ key: 'analytics',
61
+ label: 'Analytics',
62
+ count: analyticsEvents.length,
63
+ icon: 'analytics',
64
+ },
65
+ {
66
+ key: 'redux',
67
+ label: 'Redux',
68
+ count: 0,
69
+ icon: 'redux',
70
+ },
71
+ {
72
+ key: 'bundle',
73
+ label: 'Bundle',
74
+ count: 0,
75
+ icon: 'bundle',
76
+ },
77
+ {
78
+ key: 'performance',
79
+ label: 'Performance',
80
+ count: 0,
81
+ icon: 'performance',
82
+ },
83
+ {
84
+ key: 'crash',
85
+ label: 'Crash',
86
+ count: crashRecords?.length || 0,
87
+ icon: 'crash',
88
+ },
89
+ ] as const
90
+ )
91
+ .filter(tab => {
92
+ if (!tabVisibility?.[tab.key]) return false;
93
+ if (tab.key === 'redux' && !isReduxAvail) return false;
94
+ if (tab.key === 'analytics' && !isAnalyticsAvail) return false;
95
+ return true;
96
+ })
97
+ .map(tab => {
98
+ const isActive = activeTab === tab.key;
99
+ const iconColor = isActive
100
+ ? AppColors.white
101
+ : tab.key === 'crash' && tab.count > 0
102
+ ? AppColors.errorColor
103
+ : AppColors.grayText;
104
+ const countLabel =
105
+ tab.count > 9 ? '9+' : String(tab.count);
106
+ const hasUnreadApis =
107
+ activeTab !== 'apis' &&
108
+ logs.length > lastReadApisCount;
109
+ const hasUnreadLogs =
110
+ activeTab !== 'logs' &&
111
+ consoleLogs.length > lastReadLogsCount;
112
+ const hasUnreadCrashes =
113
+ activeTab !== 'crash' &&
114
+ (crashRecords?.length || 0) > (lastReadCrashesCount || 0);
115
+ return (
116
+ <TouchableScale
117
+ key={tab.key}
118
+ onPress={() => {
119
+ switchActiveTab(tab.key);
120
+ }}
121
+ style={[
122
+ styles.contentTabButton,
123
+ isActive && styles.contentTabButtonActive,
124
+ ]}>
125
+ <View
126
+ style={{
127
+ flexDirection: 'row',
128
+ alignItems: 'center',
129
+ gap: 6,
130
+ }}>
131
+ {tab.icon === 'apis' && (
132
+ <SignalIcon color={iconColor} size={14} />
133
+ )}
134
+ {tab.icon === 'logs' && (
135
+ <TerminalIcon color={iconColor} size={14} />
136
+ )}
137
+ {tab.icon === 'analytics' && (
138
+ <AnalyticsIcon color={iconColor} size={14} />
139
+ )}
140
+ {tab.icon === 'redux' && (
141
+ <ReduxIcon color={iconColor} size={14} />
142
+ )}
143
+ {tab.icon === 'bundle' && (
144
+ <PackageIcon color={iconColor} size={14} />
145
+ )}
146
+ {tab.icon === 'performance' && (
147
+ <PerformanceIcon color={iconColor} size={14} />
148
+ )}
149
+ {tab.icon === 'crash' && (
150
+ <CrashIcon color={iconColor} size={14} />
151
+ )}
152
+ <Text
153
+ numberOfLines={1}
154
+ ellipsizeMode="tail"
155
+ style={[
156
+ styles.contentTabButtonText,
157
+ isActive &&
158
+ styles.contentTabButtonTextActive,
159
+ ]}>
160
+ {tab.label}{' '}
161
+ {tab.count > 0 ? `(${countLabel})` : ''}
162
+ </Text>
163
+ {((tab.key === 'apis' && hasUnreadApis) ||
164
+ (tab.key === 'logs' && hasUnreadLogs) ||
165
+ (tab.key === 'crash' && hasUnreadCrashes)) && (
166
+ <Animated.View
167
+ style={{
168
+ width: 6,
169
+ height: 6,
170
+ borderRadius: 3,
171
+ backgroundColor: AppColors.errorColor,
172
+ marginLeft: 4,
173
+ alignSelf: 'center',
174
+ transform: [{scale: unreadPulseAnim}],
175
+ }}
176
+ />
177
+ )}
178
+ </View>
179
+ </TouchableScale>
180
+ );
181
+ })}
182
+ </ScrollView>
183
+ </View>
184
+ );
185
+ });
186
+
187
+ export default TabBar;
@@ -0,0 +1,392 @@
1
+ import React, {useState, useEffect} from 'react';
2
+ import {
3
+ Modal,
4
+ View,
5
+ Text,
6
+ TouchableOpacity,
7
+ StyleSheet,
8
+ Animated,
9
+ Platform,
10
+ } from 'react-native';
11
+ import Svg, {Path} from 'react-native-svg';
12
+ import {BrandSquareIcon} from '../BrandSquareIcon';
13
+ import {
14
+ getTelemetryConsentStatus,
15
+ setTelemetryConsent,
16
+ sendSessionTelemetryPing,
17
+ } from '../../helpers/telemetry';
18
+
19
+ // ─── Inline Crisp SVG Icons ───────────────────────────────────────────────────
20
+
21
+ const ShieldCheckSvg = ({size = 15, color = '#7C3AED'}: {size?: number; color?: string}) => (
22
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
23
+ <Path
24
+ d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"
25
+ stroke={color}
26
+ strokeWidth="2"
27
+ strokeLinecap="round"
28
+ strokeLinejoin="round"
29
+ />
30
+ <Path
31
+ d="M9 12l2 2 4-4"
32
+ stroke={color}
33
+ strokeWidth="2"
34
+ strokeLinecap="round"
35
+ strokeLinejoin="round"
36
+ />
37
+ </Svg>
38
+ );
39
+
40
+ const CheckSvg = ({size = 14, color = '#FFFFFF'}: {size?: number; color?: string}) => (
41
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
42
+ <Path
43
+ d="M20 6L9 17l-5-5"
44
+ stroke={color}
45
+ strokeWidth="2.4"
46
+ strokeLinecap="round"
47
+ strokeLinejoin="round"
48
+ />
49
+ </Svg>
50
+ );
51
+
52
+ const CloseSvg = ({size = 13, color = '#64748B'}: {size?: number; color?: string}) => (
53
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
54
+ <Path
55
+ d="M18 6L6 18M6 6l12 12"
56
+ stroke={color}
57
+ strokeWidth="2.2"
58
+ strokeLinecap="round"
59
+ strokeLinejoin="round"
60
+ />
61
+ </Svg>
62
+ );
63
+
64
+ export const TelemetryConsentModal = () => {
65
+ const [visible, setVisible] = useState(false);
66
+ const fadeAnim = useState(new Animated.Value(0))[0];
67
+ const scaleAnim = useState(new Animated.Value(0.92))[0];
68
+
69
+ useEffect(() => {
70
+ let isMounted = true;
71
+ getTelemetryConsentStatus().then(status => {
72
+ if (isMounted && status === 'undetermined') {
73
+ setVisible(true);
74
+ Animated.parallel([
75
+ Animated.timing(fadeAnim, {
76
+ toValue: 1,
77
+ duration: 250,
78
+ useNativeDriver: true,
79
+ }),
80
+ Animated.spring(scaleAnim, {
81
+ toValue: 1,
82
+ friction: 8,
83
+ tension: 45,
84
+ useNativeDriver: true,
85
+ }),
86
+ ]).start();
87
+ }
88
+ });
89
+ return () => {
90
+ isMounted = false;
91
+ };
92
+ }, [fadeAnim, scaleAnim]);
93
+
94
+ const handleDecision = async (granted: boolean) => {
95
+ Animated.parallel([
96
+ Animated.timing(fadeAnim, {
97
+ toValue: 0,
98
+ duration: 180,
99
+ useNativeDriver: true,
100
+ }),
101
+ Animated.timing(scaleAnim, {
102
+ toValue: 0.92,
103
+ duration: 180,
104
+ useNativeDriver: true,
105
+ }),
106
+ ]).start(async () => {
107
+ setVisible(false);
108
+ await setTelemetryConsent(granted);
109
+ if (granted) {
110
+ // Immediately trigger the session initialization ping
111
+ sendSessionTelemetryPing({force: true});
112
+ }
113
+ });
114
+ };
115
+
116
+ if (!visible) return null;
117
+
118
+ return (
119
+ <Modal
120
+ transparent
121
+ visible={visible}
122
+ animationType="none"
123
+ statusBarTranslucent>
124
+ <View style={styles.overlay}>
125
+ <Animated.View
126
+ style={[
127
+ styles.card,
128
+ {
129
+ opacity: fadeAnim,
130
+ transform: [{scale: scaleAnim}],
131
+ },
132
+ ]}>
133
+ {/* Top-Right Dismiss Icon Button */}
134
+ <TouchableOpacity
135
+ style={styles.topCloseButton}
136
+ onPress={() => handleDecision(false)}
137
+ hitSlop={10}
138
+ activeOpacity={0.7}>
139
+ <CloseSvg size={13} color="#64748B" />
140
+ </TouchableOpacity>
141
+
142
+ {/* Centered Enlarged Square Brand Icon Header */}
143
+ <View style={styles.headerSection}>
144
+ <View style={styles.iconHaloRing}>
145
+ <BrandSquareIcon size={54} />
146
+ </View>
147
+
148
+ <Text style={styles.title}>Help Improve In-App Inspector</Text>
149
+ <Text style={styles.subtitle}>Anonymous Diagnostic Insights</Text>
150
+
151
+ {/* Subheading instruction hint badge */}
152
+ <View style={styles.hintBadge}>
153
+ <Text style={styles.hintBadgeText}>
154
+ ⚙️ You can enable or disable this anytime in Settings
155
+ </Text>
156
+ </View>
157
+ </View>
158
+
159
+ {/* Description */}
160
+ <Text style={styles.description}>
161
+ To help us continually enhance tooling performance and compatibility,
162
+ would you mind sharing anonymous diagnostics (such as React Native
163
+ version, JavaScript engine, and device architecture)?
164
+ </Text>
165
+
166
+ {/* Privacy Callout Box */}
167
+ <View style={styles.privacyBadge}>
168
+ <View style={styles.privacyShieldWrapper}>
169
+ <ShieldCheckSvg size={15} color="#7C3AED" />
170
+ </View>
171
+ <Text style={styles.privacyText}>
172
+ <Text style={styles.privacyHighlight}>Privacy Guaranteed:</Text> We
173
+ strictly collect non-identifiable technical metrics. No user data,
174
+ passwords, tokens, or network payload bodies are ever captured.
175
+ </Text>
176
+ </View>
177
+
178
+ {/* Enhanced Action Buttons with Icons */}
179
+ <View style={styles.buttonRow}>
180
+ <TouchableOpacity
181
+ style={styles.declineButton}
182
+ onPress={() => handleDecision(false)}
183
+ activeOpacity={0.7}>
184
+ <CloseSvg size={12} color="#64748B" />
185
+ <Text style={styles.declineText}>Not Now</Text>
186
+ </TouchableOpacity>
187
+
188
+ <TouchableOpacity
189
+ style={styles.allowButton}
190
+ onPress={() => handleDecision(true)}
191
+ activeOpacity={0.85}>
192
+ <CheckSvg size={13} color="#FFFFFF" />
193
+ <Text style={styles.allowText}>Allow & Share</Text>
194
+ </TouchableOpacity>
195
+ </View>
196
+ </Animated.View>
197
+ </View>
198
+ </Modal>
199
+ );
200
+ };
201
+
202
+ const fontStack = Platform.select({
203
+ ios: {
204
+ fontFamily: 'System',
205
+ },
206
+ android: {
207
+ fontFamily: 'sans-serif',
208
+ },
209
+ default: {},
210
+ });
211
+
212
+ const styles = StyleSheet.create({
213
+ overlay: {
214
+ flex: 1,
215
+ backgroundColor: 'rgba(15, 23, 42, 0.56)',
216
+ justifyContent: 'center',
217
+ alignItems: 'center',
218
+ paddingHorizontal: 20,
219
+ zIndex: 999999,
220
+ },
221
+ card: {
222
+ width: '100%',
223
+ maxWidth: 356,
224
+ backgroundColor: '#FFFFFF',
225
+ borderRadius: 24,
226
+ borderWidth: 1,
227
+ borderColor: '#E2E8F0',
228
+ paddingHorizontal: 20,
229
+ paddingTop: 22,
230
+ paddingBottom: 20,
231
+ alignItems: 'center',
232
+ shadowColor: '#0F172A',
233
+ shadowOffset: {width: 0, height: 16},
234
+ shadowOpacity: 0.22,
235
+ shadowRadius: 32,
236
+ elevation: 24,
237
+ },
238
+ topCloseButton: {
239
+ position: 'absolute',
240
+ top: 14,
241
+ right: 14,
242
+ width: 28,
243
+ height: 28,
244
+ borderRadius: 14,
245
+ backgroundColor: '#F8FAFC',
246
+ justifyContent: 'center',
247
+ alignItems: 'center',
248
+ borderWidth: 1,
249
+ borderColor: '#E2E8F0',
250
+ zIndex: 10,
251
+ },
252
+ headerSection: {
253
+ alignItems: 'center',
254
+ width: '100%',
255
+ marginBottom: 4,
256
+ },
257
+ iconHaloRing: {
258
+ width: 66,
259
+ height: 66,
260
+ borderRadius: 20,
261
+ backgroundColor: '#FAF5FF',
262
+ justifyContent: 'center',
263
+ alignItems: 'center',
264
+ borderWidth: 1.5,
265
+ borderColor: '#F3E8FF',
266
+ marginBottom: 8,
267
+ shadowColor: '#7C3AED',
268
+ shadowOffset: {width: 0, height: 4},
269
+ shadowOpacity: 0.16,
270
+ shadowRadius: 10,
271
+ elevation: 4,
272
+ },
273
+ title: {
274
+ fontSize: 17,
275
+ fontWeight: '800',
276
+ color: '#0F172A',
277
+ letterSpacing: -0.4,
278
+ textAlign: 'center',
279
+ lineHeight: 22,
280
+ marginBottom: 2,
281
+ ...fontStack,
282
+ },
283
+ subtitle: {
284
+ fontSize: 11.5,
285
+ fontWeight: '600',
286
+ color: '#7C3AED',
287
+ textAlign: 'center',
288
+ letterSpacing: 0.2,
289
+ marginBottom: 6,
290
+ ...fontStack,
291
+ },
292
+ hintBadge: {
293
+ backgroundColor: '#EDE9FE80',
294
+ borderWidth: 1,
295
+ borderColor: '#DDD6FE',
296
+ borderRadius: 7,
297
+ paddingHorizontal: 8,
298
+ paddingVertical: 2.5,
299
+ marginBottom: 8,
300
+ },
301
+ hintBadgeText: {
302
+ fontSize: 10,
303
+ fontWeight: '600',
304
+ color: '#6D28D9',
305
+ textAlign: 'center',
306
+ ...fontStack,
307
+ },
308
+ description: {
309
+ fontSize: 12,
310
+ lineHeight: 17.5,
311
+ color: '#475569',
312
+ textAlign: 'center',
313
+ marginBottom: 12,
314
+ paddingHorizontal: 2,
315
+ ...fontStack,
316
+ },
317
+ privacyBadge: {
318
+ flexDirection: 'row',
319
+ alignItems: 'flex-start',
320
+ backgroundColor: '#F8FAFC',
321
+ borderRadius: 12,
322
+ paddingVertical: 8,
323
+ paddingHorizontal: 10,
324
+ borderWidth: 1,
325
+ borderColor: '#E2E8F0',
326
+ marginBottom: 14,
327
+ width: '100%',
328
+ },
329
+ privacyShieldWrapper: {
330
+ marginRight: 7,
331
+ marginTop: 1,
332
+ },
333
+ privacyText: {
334
+ flex: 1,
335
+ fontSize: 10.8,
336
+ lineHeight: 15,
337
+ color: '#475569',
338
+ ...fontStack,
339
+ },
340
+ privacyHighlight: {
341
+ fontWeight: '700',
342
+ color: '#1E293B',
343
+ },
344
+ buttonRow: {
345
+ flexDirection: 'row',
346
+ justifyContent: 'space-between',
347
+ alignItems: 'center',
348
+ gap: 10,
349
+ width: '100%',
350
+ },
351
+ declineButton: {
352
+ flex: 1,
353
+ flexDirection: 'row',
354
+ alignItems: 'center',
355
+ justifyContent: 'center',
356
+ gap: 5,
357
+ paddingVertical: 11,
358
+ borderRadius: 12,
359
+ backgroundColor: '#F1F5F9',
360
+ borderWidth: 1,
361
+ borderColor: '#E2E8F0',
362
+ },
363
+ declineText: {
364
+ fontSize: 13,
365
+ fontWeight: '600',
366
+ color: '#475569',
367
+ ...fontStack,
368
+ },
369
+ allowButton: {
370
+ flex: 1,
371
+ flexDirection: 'row',
372
+ alignItems: 'center',
373
+ justifyContent: 'center',
374
+ gap: 5,
375
+ paddingVertical: 11,
376
+ borderRadius: 12,
377
+ backgroundColor: '#7C3AED',
378
+ shadowColor: '#7C3AED',
379
+ shadowOffset: {width: 0, height: 3},
380
+ shadowOpacity: 0.28,
381
+ shadowRadius: 6,
382
+ elevation: 4,
383
+ },
384
+ allowText: {
385
+ fontSize: 13,
386
+ fontWeight: '700',
387
+ color: '#FFFFFF',
388
+ ...fontStack,
389
+ },
390
+ });
391
+
392
+ export default TelemetryConsentModal;