react-native-inapp-inspector 2.0.2 → 2.0.4

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 (42) hide show
  1. package/dist/commonjs/components/AppHeaderLogo.js +21 -2
  2. package/dist/commonjs/components/Inspector/InspectorHeader.js +84 -11
  3. package/dist/commonjs/components/Inspector/MainScreen.js +6 -2
  4. package/dist/commonjs/components/Inspector/NpmUpdateToast.d.ts +3 -0
  5. package/dist/commonjs/components/Inspector/NpmUpdateToast.js +288 -0
  6. package/dist/commonjs/components/Inspector/SettingsPanel.js +192 -1
  7. package/dist/commonjs/components/Inspector/TelemetryConsentModal.js +218 -71
  8. package/dist/commonjs/constants/version.d.ts +1 -1
  9. package/dist/commonjs/constants/version.js +1 -1
  10. package/dist/commonjs/helpers/telemetry.js +4 -4
  11. package/dist/commonjs/index.js +14 -2
  12. package/dist/commonjs/types/interfaces.d.ts +5 -0
  13. package/dist/esm/components/AppHeaderLogo.js +21 -2
  14. package/dist/esm/components/Inspector/InspectorHeader.js +85 -12
  15. package/dist/esm/components/Inspector/MainScreen.js +6 -2
  16. package/dist/esm/components/Inspector/NpmUpdateToast.d.ts +3 -0
  17. package/dist/esm/components/Inspector/NpmUpdateToast.js +251 -0
  18. package/dist/esm/components/Inspector/SettingsPanel.js +192 -1
  19. package/dist/esm/components/Inspector/TelemetryConsentModal.js +219 -72
  20. package/dist/esm/constants/version.d.ts +1 -1
  21. package/dist/esm/constants/version.js +1 -1
  22. package/dist/esm/helpers/telemetry.js +4 -4
  23. package/dist/esm/index.js +14 -2
  24. package/dist/esm/types/interfaces.d.ts +5 -0
  25. package/package.json +1 -1
  26. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  27. package/android/.gradle/8.9/checksums/md5-checksums.bin +0 -0
  28. package/android/.gradle/8.9/checksums/sha1-checksums.bin +0 -0
  29. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  30. package/android/.gradle/8.9/executionHistory/executionHistory.lock +0 -0
  31. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  32. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  33. package/android/.gradle/8.9/gc.properties +0 -0
  34. package/android/.gradle/9.2.0/checksums/checksums.lock +0 -0
  35. package/android/.gradle/9.2.0/fileChanges/last-build.bin +0 -0
  36. package/android/.gradle/9.2.0/fileHashes/fileHashes.bin +0 -0
  37. package/android/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
  38. package/android/.gradle/9.2.0/gc.properties +0 -0
  39. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  40. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  41. package/android/.gradle/vcs-1/gc.properties +0 -0
  42. package/android/build/reports/problems/problems-report.html +0 -659
@@ -17,11 +17,26 @@ import { clearPerformanceEvents } from '../../customHooks/performanceTracker';
17
17
  import { isReduxConnected } from '../../customHooks/reduxLogger';
18
18
  import { isAnalyticsConnected } from '../../customHooks/analyticsLogger';
19
19
  import { useTranslation } from '../../i18n';
20
+ import { getTelemetryConsentStatus, setTelemetryConsent, sendSessionTelemetryPing, } from '../../helpers/telemetry';
20
21
  import { SignalIcon, TerminalIcon, AnalyticsIcon, SettingsIcon, SunIcon, MoonIcon, ScreenIcon, MotionIcon, LayersIcon, EyeIcon, CheckIcon, TrashIcon, PackageIcon, ReduxIcon, PerformanceIcon, CrashIcon, ShieldAlertIcon, ForwardChevronIcon, ChevronDownIcon, } from '../NetworkIcons';
21
22
  const SettingsPanel = () => {
22
23
  const { t } = useTranslation();
23
- const { settingsPage, setSettingsPage, settingsActiveSubTab, setSettingsActiveSubTab, tabVisibility, toggleTabVisibility, defaultTab, setDefaultTab, isDark, setIsDark, modalHeightPercent, setModalHeightPercent, modalAnimationType, setModalAnimationType, showDuplicateLogs, setShowDuplicateLogs, showConsoleLevels, setShowConsoleLevels, resetToDefaults, storage, logs, consoleLogs, analyticsEvents, reduxState, maxNetworkLogs, setMaxNetworkLogs, maxConsoleLogs, setMaxConsoleLogs, maxAnalyticsEventsLimit, setMaxAnalyticsEventsLimit, isAutoRamLimitEnabled, setIsAutoRamLimitEnabled, deviceFreeRamMb, reduxAutoRefresh, setReduxAutoRefreshState, reduxExpandDepth, setReduxExpandDepth, switchActiveTab, setSelected, setSelectedEvent, setReduxState, crashRecords, maxCrashLogs, setMaxCrashLogs, } = useInspector();
24
+ const { settingsPage, setSettingsPage, settingsActiveSubTab, setSettingsActiveSubTab, tabVisibility, toggleTabVisibility, defaultTab, setDefaultTab, isDark, setIsDark, modalHeightPercent, setModalHeightPercent, modalAnimationType, setModalAnimationType, showDuplicateLogs, setShowDuplicateLogs, showUpdateToast, setShowUpdateToast, showConsoleLevels, setShowConsoleLevels, resetToDefaults, storage, logs, consoleLogs, analyticsEvents, reduxState, maxNetworkLogs, setMaxNetworkLogs, maxConsoleLogs, setMaxConsoleLogs, maxAnalyticsEventsLimit, setMaxAnalyticsEventsLimit, isAutoRamLimitEnabled, setIsAutoRamLimitEnabled, deviceFreeRamMb, reduxAutoRefresh, setReduxAutoRefreshState, reduxExpandDepth, setReduxExpandDepth, switchActiveTab, setSelected, setSelectedEvent, setReduxState, crashRecords, maxCrashLogs, setMaxCrashLogs, } = useInspector();
24
25
  const [stagedHeight, setStagedHeight] = useState(modalHeightPercent);
26
+ const [telemetryConsent, setTelemetryConsentState] = useState(true);
27
+ useEffect(() => {
28
+ getTelemetryConsentStatus().then(status => {
29
+ setTelemetryConsentState(status === 'granted');
30
+ });
31
+ }, []);
32
+ const handleToggleTelemetry = async () => {
33
+ const nextVal = !telemetryConsent;
34
+ setTelemetryConsentState(nextVal);
35
+ await setTelemetryConsent(nextVal);
36
+ if (nextVal) {
37
+ sendSessionTelemetryPing({ force: true });
38
+ }
39
+ };
25
40
  useEffect(() => {
26
41
  setStagedHeight(modalHeightPercent);
27
42
  }, [modalHeightPercent]);
@@ -1315,6 +1330,182 @@ const SettingsPanel = () => {
1315
1330
  </View>)}
1316
1331
  </View>
1317
1332
  </View>
1333
+
1334
+ {/* Section 4: Privacy & Diagnostics */}
1335
+ <View style={{
1336
+ backgroundColor: AppColors.primaryLight,
1337
+ borderRadius: 14,
1338
+ borderWidth: 1,
1339
+ borderColor: AppColors.grayBorderSecondary,
1340
+ overflow: 'hidden',
1341
+ padding: 14,
1342
+ gap: 12,
1343
+ }}>
1344
+ <Text style={{
1345
+ fontFamily: AppFonts.interBold,
1346
+ fontSize: 11,
1347
+ lineHeight: 14,
1348
+ color: AppColors.grayTextWeak,
1349
+ letterSpacing: 0.8,
1350
+ }}>
1351
+ PRIVACY & ANONYMOUS DIAGNOSTICS
1352
+ </Text>
1353
+
1354
+ <View style={{
1355
+ flexDirection: 'row',
1356
+ alignItems: 'center',
1357
+ justifyContent: 'space-between',
1358
+ }}>
1359
+ <View style={{
1360
+ flexDirection: 'row',
1361
+ alignItems: 'center',
1362
+ gap: 10,
1363
+ flex: 1,
1364
+ marginRight: 10,
1365
+ }}>
1366
+ <View style={{
1367
+ width: 32,
1368
+ height: 32,
1369
+ borderRadius: 8,
1370
+ backgroundColor: AppColors.purpleShade50,
1371
+ alignItems: 'center',
1372
+ justifyContent: 'center',
1373
+ }}>
1374
+ <ShieldAlertIcon color={AppColors.purple} size={15}/>
1375
+ </View>
1376
+ <View style={{ flex: 1 }}>
1377
+ <Text style={{
1378
+ fontFamily: AppFonts.interBold,
1379
+ fontSize: 13.5,
1380
+ lineHeight: 18,
1381
+ color: AppColors.primaryBlack,
1382
+ }}>
1383
+ Help Improve In-App Inspector
1384
+ </Text>
1385
+ <Text style={{
1386
+ fontFamily: AppFonts.interRegular,
1387
+ fontSize: 11,
1388
+ lineHeight: 15,
1389
+ color: AppColors.grayText,
1390
+ marginTop: 1,
1391
+ }}>
1392
+ Share non-identifiable technical metrics (RN version, JS engine, device model). No user data or network payloads are captured.
1393
+ </Text>
1394
+ </View>
1395
+ </View>
1396
+
1397
+ <TouchableScale accessible={true} accessibilityRole="switch" accessibilityLabel="Toggle Anonymous Telemetry" accessibilityState={{ checked: telemetryConsent }} onPress={handleToggleTelemetry} style={{
1398
+ width: 42,
1399
+ height: 24,
1400
+ borderRadius: 12,
1401
+ backgroundColor: telemetryConsent
1402
+ ? AppColors.purple
1403
+ : AppColors.grayBorderSecondary,
1404
+ padding: 2,
1405
+ justifyContent: 'center',
1406
+ alignItems: telemetryConsent ? 'flex-end' : 'flex-start',
1407
+ }}>
1408
+ <View style={{
1409
+ width: 20,
1410
+ height: 20,
1411
+ borderRadius: 10,
1412
+ backgroundColor: AppColors.white,
1413
+ shadowColor: AppColors.black,
1414
+ shadowOpacity: 0.18,
1415
+ shadowRadius: 2,
1416
+ shadowOffset: { width: 0, height: 1 },
1417
+ }}/>
1418
+ </TouchableScale>
1419
+ </View>
1420
+ </View>
1421
+
1422
+ {/* Section 5: Notifications & Toasts */}
1423
+ <View style={{
1424
+ backgroundColor: AppColors.primaryLight,
1425
+ borderRadius: 14,
1426
+ borderWidth: 1,
1427
+ borderColor: AppColors.grayBorderSecondary,
1428
+ overflow: 'hidden',
1429
+ padding: 14,
1430
+ gap: 12,
1431
+ }}>
1432
+ <Text style={{
1433
+ fontFamily: AppFonts.interBold,
1434
+ fontSize: 11,
1435
+ lineHeight: 14,
1436
+ color: AppColors.grayTextWeak,
1437
+ letterSpacing: 0.8,
1438
+ }}>
1439
+ NOTIFICATIONS & TOASTS
1440
+ </Text>
1441
+
1442
+ <View style={{
1443
+ flexDirection: 'row',
1444
+ alignItems: 'center',
1445
+ justifyContent: 'space-between',
1446
+ }}>
1447
+ <View style={{
1448
+ flexDirection: 'row',
1449
+ alignItems: 'center',
1450
+ gap: 10,
1451
+ flex: 1,
1452
+ marginRight: 10,
1453
+ }}>
1454
+ <View style={{
1455
+ width: 32,
1456
+ height: 32,
1457
+ borderRadius: 8,
1458
+ backgroundColor: AppColors.purpleShade50,
1459
+ alignItems: 'center',
1460
+ justifyContent: 'center',
1461
+ }}>
1462
+ <PackageIcon color={AppColors.purple} size={15}/>
1463
+ </View>
1464
+ <View style={{ flex: 1 }}>
1465
+ <Text style={{
1466
+ fontFamily: AppFonts.interBold,
1467
+ fontSize: 13.5,
1468
+ lineHeight: 18,
1469
+ color: AppColors.primaryBlack,
1470
+ }}>
1471
+ NPM Update Toast
1472
+ </Text>
1473
+ <Text style={{
1474
+ fontFamily: AppFonts.interRegular,
1475
+ fontSize: 11,
1476
+ lineHeight: 15,
1477
+ color: AppColors.grayText,
1478
+ marginTop: 1,
1479
+ }}>
1480
+ Show a floating toast banner with countdown progress when a newer release is published on npm.
1481
+ </Text>
1482
+ </View>
1483
+ </View>
1484
+
1485
+ <TouchableScale accessible={true} accessibilityRole="switch" accessibilityLabel="Toggle NPM Update Toast" accessibilityState={{ checked: showUpdateToast }} onPress={() => setShowUpdateToast(prev => !prev)} style={{
1486
+ width: 42,
1487
+ height: 24,
1488
+ borderRadius: 12,
1489
+ backgroundColor: showUpdateToast
1490
+ ? AppColors.purple
1491
+ : AppColors.grayBorderSecondary,
1492
+ padding: 2,
1493
+ justifyContent: 'center',
1494
+ alignItems: showUpdateToast ? 'flex-end' : 'flex-start',
1495
+ }}>
1496
+ <View style={{
1497
+ width: 20,
1498
+ height: 20,
1499
+ borderRadius: 10,
1500
+ backgroundColor: AppColors.white,
1501
+ shadowColor: AppColors.black,
1502
+ shadowOpacity: 0.18,
1503
+ shadowRadius: 2,
1504
+ shadowOffset: { width: 0, height: 1 },
1505
+ }}/>
1506
+ </TouchableScale>
1507
+ </View>
1508
+ </View>
1318
1509
  </View>)}
1319
1510
  <View style={{ height: 48 }}/>
1320
1511
  </ScrollView>
@@ -1,33 +1,60 @@
1
1
  import React, { useState, useEffect } from 'react';
2
- import { Modal, View, Text, TouchableOpacity, StyleSheet, Animated, } from 'react-native';
3
- import { AppColors } from '../../styles/AppColors';
4
- import { BrandCircleIcon } from '../BrandCircleIcon';
2
+ import { Modal, View, Text, TouchableOpacity, StyleSheet, Animated, Platform, } from 'react-native';
3
+ import Svg, { Path } from 'react-native-svg';
4
+ import { BrandSquareIcon } from '../BrandSquareIcon';
5
5
  import { getTelemetryConsentStatus, setTelemetryConsent, sendSessionTelemetryPing, } from '../../helpers/telemetry';
6
+ // ─── Inline Crisp SVG Icons ───────────────────────────────────────────────────
7
+ const ShieldCheckSvg = ({ size = 15, color = '#7C3AED' }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
8
+ <Path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
9
+ <Path d="M9 12l2 2 4-4" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
10
+ </Svg>);
11
+ const CheckSvg = ({ size = 14, color = '#FFFFFF' }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
12
+ <Path d="M20 6L9 17l-5-5" stroke={color} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"/>
13
+ </Svg>);
14
+ const CloseSvg = ({ size = 13, color = '#64748B' }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
15
+ <Path d="M18 6L6 18M6 6l12 12" stroke={color} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
16
+ </Svg>);
6
17
  export const TelemetryConsentModal = () => {
7
18
  const [visible, setVisible] = useState(false);
8
19
  const fadeAnim = useState(new Animated.Value(0))[0];
20
+ const scaleAnim = useState(new Animated.Value(0.92))[0];
9
21
  useEffect(() => {
10
22
  let isMounted = true;
11
23
  getTelemetryConsentStatus().then(status => {
12
24
  if (isMounted && status === 'undetermined') {
13
25
  setVisible(true);
14
- Animated.timing(fadeAnim, {
15
- toValue: 1,
16
- duration: 300,
17
- useNativeDriver: true,
18
- }).start();
26
+ Animated.parallel([
27
+ Animated.timing(fadeAnim, {
28
+ toValue: 1,
29
+ duration: 250,
30
+ useNativeDriver: true,
31
+ }),
32
+ Animated.spring(scaleAnim, {
33
+ toValue: 1,
34
+ friction: 8,
35
+ tension: 45,
36
+ useNativeDriver: true,
37
+ }),
38
+ ]).start();
19
39
  }
20
40
  });
21
41
  return () => {
22
42
  isMounted = false;
23
43
  };
24
- }, [fadeAnim]);
44
+ }, [fadeAnim, scaleAnim]);
25
45
  const handleDecision = async (granted) => {
26
- Animated.timing(fadeAnim, {
27
- toValue: 0,
28
- duration: 200,
29
- useNativeDriver: true,
30
- }).start(async () => {
46
+ Animated.parallel([
47
+ Animated.timing(fadeAnim, {
48
+ toValue: 0,
49
+ duration: 180,
50
+ useNativeDriver: true,
51
+ }),
52
+ Animated.timing(scaleAnim, {
53
+ toValue: 0.92,
54
+ duration: 180,
55
+ useNativeDriver: true,
56
+ }),
57
+ ]).start(async () => {
31
58
  setVisible(false);
32
59
  await setTelemetryConsent(granted);
33
60
  if (granted) {
@@ -40,37 +67,63 @@ export const TelemetryConsentModal = () => {
40
67
  return null;
41
68
  return (<Modal transparent visible={visible} animationType="none" statusBarTranslucent>
42
69
  <View style={styles.overlay}>
43
- <Animated.View style={[styles.card, { opacity: fadeAnim }]}>
44
- <View style={styles.headerRow}>
45
- <View style={styles.iconWrapper}>
46
- <BrandCircleIcon size={40}/>
70
+ <Animated.View style={[
71
+ styles.card,
72
+ {
73
+ opacity: fadeAnim,
74
+ transform: [{ scale: scaleAnim }],
75
+ },
76
+ ]}>
77
+ {/* Top-Right Dismiss Icon Button */}
78
+ <TouchableOpacity style={styles.topCloseButton} onPress={() => handleDecision(false)} hitSlop={10} activeOpacity={0.7}>
79
+ <CloseSvg size={13} color="#64748B"/>
80
+ </TouchableOpacity>
81
+
82
+ {/* Centered Enlarged Square Brand Icon Header */}
83
+ <View style={styles.headerSection}>
84
+ <View style={styles.iconHaloRing}>
85
+ <BrandSquareIcon size={54}/>
47
86
  </View>
48
- <View style={styles.titleContainer}>
49
- <Text style={styles.title}>Help Improve In-App Inspector</Text>
50
- <Text style={styles.subtitle}>Anonymous Diagnostic Insights</Text>
87
+
88
+ <Text style={styles.title}>Help Improve In-App Inspector</Text>
89
+ <Text style={styles.subtitle}>Anonymous Diagnostic Insights</Text>
90
+
91
+ {/* Subheading instruction hint badge */}
92
+ <View style={styles.hintBadge}>
93
+ <Text style={styles.hintBadgeText}>
94
+ ⚙️ You can enable or disable this anytime in Settings
95
+ </Text>
51
96
  </View>
52
97
  </View>
53
98
 
99
+ {/* Description */}
54
100
  <Text style={styles.description}>
55
101
  To help us continually enhance tooling performance and compatibility,
56
102
  would you mind sharing anonymous diagnostics (such as React Native
57
- version, JavaScript engine, and platform architecture)?
103
+ version, JavaScript engine, and device architecture)?
58
104
  </Text>
59
105
 
106
+ {/* Privacy Callout Box */}
60
107
  <View style={styles.privacyBadge}>
108
+ <View style={styles.privacyShieldWrapper}>
109
+ <ShieldCheckSvg size={15} color="#7C3AED"/>
110
+ </View>
61
111
  <Text style={styles.privacyText}>
62
- 🔒 <Text style={{ fontWeight: '700' }}>Privacy Guaranteed:</Text> We
63
- only collect non-identifiable environment metrics. No personal
64
- data, tokens, or network request payloads are ever collected.
112
+ <Text style={styles.privacyHighlight}>Privacy Guaranteed:</Text> We
113
+ strictly collect non-identifiable technical metrics. No user data,
114
+ passwords, tokens, or network payload bodies are ever captured.
65
115
  </Text>
66
116
  </View>
67
117
 
118
+ {/* Enhanced Action Buttons with Icons */}
68
119
  <View style={styles.buttonRow}>
69
120
  <TouchableOpacity style={styles.declineButton} onPress={() => handleDecision(false)} activeOpacity={0.7}>
121
+ <CloseSvg size={12} color="#64748B"/>
70
122
  <Text style={styles.declineText}>Not Now</Text>
71
123
  </TouchableOpacity>
72
124
 
73
- <TouchableOpacity style={styles.allowButton} onPress={() => handleDecision(true)} activeOpacity={0.8}>
125
+ <TouchableOpacity style={styles.allowButton} onPress={() => handleDecision(true)} activeOpacity={0.85}>
126
+ <CheckSvg size={13} color="#FFFFFF"/>
74
127
  <Text style={styles.allowText}>Allow & Share</Text>
75
128
  </TouchableOpacity>
76
129
  </View>
@@ -78,98 +131,192 @@ export const TelemetryConsentModal = () => {
78
131
  </View>
79
132
  </Modal>);
80
133
  };
134
+ const fontStack = Platform.select({
135
+ ios: {
136
+ fontFamily: 'System',
137
+ },
138
+ android: {
139
+ fontFamily: 'sans-serif',
140
+ },
141
+ default: {},
142
+ });
81
143
  const styles = StyleSheet.create({
82
144
  overlay: {
83
145
  flex: 1,
84
- backgroundColor: 'rgba(0, 0, 0, 0.65)',
146
+ backgroundColor: 'rgba(15, 23, 42, 0.56)',
85
147
  justifyContent: 'center',
86
148
  alignItems: 'center',
87
- padding: 24,
149
+ paddingHorizontal: 20,
88
150
  zIndex: 999999,
89
151
  },
90
152
  card: {
91
153
  width: '100%',
92
- maxWidth: 420,
93
- backgroundColor: '#1E1F29',
94
- borderRadius: 20,
95
- padding: 22,
154
+ maxWidth: 356,
155
+ backgroundColor: '#FFFFFF',
156
+ borderRadius: 24,
96
157
  borderWidth: 1,
97
- borderColor: 'rgba(255, 255, 255, 0.12)',
98
- shadowColor: '#000',
99
- shadowOffset: { width: 0, height: 10 },
100
- shadowOpacity: 0.5,
101
- shadowRadius: 20,
158
+ borderColor: '#E2E8F0',
159
+ paddingHorizontal: 20,
160
+ paddingTop: 22,
161
+ paddingBottom: 20,
162
+ alignItems: 'center',
163
+ shadowColor: '#0F172A',
164
+ shadowOffset: { width: 0, height: 16 },
165
+ shadowOpacity: 0.22,
166
+ shadowRadius: 32,
102
167
  elevation: 24,
103
168
  },
104
- headerRow: {
105
- flexDirection: 'row',
169
+ topCloseButton: {
170
+ position: 'absolute',
171
+ top: 14,
172
+ right: 14,
173
+ width: 28,
174
+ height: 28,
175
+ borderRadius: 14,
176
+ backgroundColor: '#F8FAFC',
177
+ justifyContent: 'center',
106
178
  alignItems: 'center',
107
- marginBottom: 14,
179
+ borderWidth: 1,
180
+ borderColor: '#E2E8F0',
181
+ zIndex: 10,
108
182
  },
109
- iconWrapper: {
110
- marginRight: 14,
183
+ headerSection: {
184
+ alignItems: 'center',
185
+ width: '100%',
186
+ marginBottom: 4,
111
187
  },
112
- titleContainer: {
113
- flex: 1,
188
+ iconHaloRing: {
189
+ width: 66,
190
+ height: 66,
191
+ borderRadius: 20,
192
+ backgroundColor: '#FAF5FF',
193
+ justifyContent: 'center',
194
+ alignItems: 'center',
195
+ borderWidth: 1.5,
196
+ borderColor: '#F3E8FF',
197
+ marginBottom: 8,
198
+ shadowColor: '#7C3AED',
199
+ shadowOffset: { width: 0, height: 4 },
200
+ shadowOpacity: 0.16,
201
+ shadowRadius: 10,
202
+ elevation: 4,
114
203
  },
115
204
  title: {
116
205
  fontSize: 17,
117
- fontWeight: '700',
118
- color: '#FFFFFF',
119
- letterSpacing: -0.2,
206
+ fontWeight: '800',
207
+ color: '#0F172A',
208
+ letterSpacing: -0.4,
209
+ textAlign: 'center',
210
+ lineHeight: 22,
211
+ marginBottom: 2,
212
+ ...fontStack,
120
213
  },
121
214
  subtitle: {
122
- fontSize: 12,
123
- color: AppColors.purple || '#9055FF',
215
+ fontSize: 11.5,
124
216
  fontWeight: '600',
125
- marginTop: 2,
217
+ color: '#7C3AED',
218
+ textAlign: 'center',
219
+ letterSpacing: 0.2,
220
+ marginBottom: 6,
221
+ ...fontStack,
222
+ },
223
+ hintBadge: {
224
+ backgroundColor: '#EDE9FE80',
225
+ borderWidth: 1,
226
+ borderColor: '#DDD6FE',
227
+ borderRadius: 7,
228
+ paddingHorizontal: 8,
229
+ paddingVertical: 2.5,
230
+ marginBottom: 8,
231
+ },
232
+ hintBadgeText: {
233
+ fontSize: 10,
234
+ fontWeight: '600',
235
+ color: '#6D28D9',
236
+ textAlign: 'center',
237
+ ...fontStack,
126
238
  },
127
239
  description: {
128
- fontSize: 13,
129
- lineHeight: 19,
130
- color: 'rgba(255, 255, 255, 0.75)',
131
- marginBottom: 14,
240
+ fontSize: 12,
241
+ lineHeight: 17.5,
242
+ color: '#475569',
243
+ textAlign: 'center',
244
+ marginBottom: 12,
245
+ paddingHorizontal: 2,
246
+ ...fontStack,
132
247
  },
133
248
  privacyBadge: {
134
- backgroundColor: 'rgba(144, 85, 255, 0.12)',
135
- borderRadius: 10,
136
- padding: 10,
249
+ flexDirection: 'row',
250
+ alignItems: 'flex-start',
251
+ backgroundColor: '#F8FAFC',
252
+ borderRadius: 12,
253
+ paddingVertical: 8,
254
+ paddingHorizontal: 10,
137
255
  borderWidth: 1,
138
- borderColor: 'rgba(144, 85, 255, 0.25)',
139
- marginBottom: 20,
256
+ borderColor: '#E2E8F0',
257
+ marginBottom: 14,
258
+ width: '100%',
259
+ },
260
+ privacyShieldWrapper: {
261
+ marginRight: 7,
262
+ marginTop: 1,
140
263
  },
141
264
  privacyText: {
142
- fontSize: 11,
143
- lineHeight: 16,
144
- color: '#D8C6FF',
265
+ flex: 1,
266
+ fontSize: 10.8,
267
+ lineHeight: 15,
268
+ color: '#475569',
269
+ ...fontStack,
270
+ },
271
+ privacyHighlight: {
272
+ fontWeight: '700',
273
+ color: '#1E293B',
145
274
  },
146
275
  buttonRow: {
147
276
  flexDirection: 'row',
148
- justifyContent: 'flex-end',
277
+ justifyContent: 'space-between',
149
278
  alignItems: 'center',
150
- gap: 12,
279
+ gap: 10,
280
+ width: '100%',
151
281
  },
152
282
  declineButton: {
153
- paddingVertical: 10,
154
- paddingHorizontal: 16,
155
- borderRadius: 10,
156
- backgroundColor: 'rgba(255, 255, 255, 0.08)',
283
+ flex: 1,
284
+ flexDirection: 'row',
285
+ alignItems: 'center',
286
+ justifyContent: 'center',
287
+ gap: 5,
288
+ paddingVertical: 11,
289
+ borderRadius: 12,
290
+ backgroundColor: '#F1F5F9',
291
+ borderWidth: 1,
292
+ borderColor: '#E2E8F0',
157
293
  },
158
294
  declineText: {
159
295
  fontSize: 13,
160
296
  fontWeight: '600',
161
- color: 'rgba(255, 255, 255, 0.7)',
297
+ color: '#475569',
298
+ ...fontStack,
162
299
  },
163
300
  allowButton: {
164
- paddingVertical: 10,
165
- paddingHorizontal: 20,
166
- borderRadius: 10,
301
+ flex: 1,
302
+ flexDirection: 'row',
303
+ alignItems: 'center',
304
+ justifyContent: 'center',
305
+ gap: 5,
306
+ paddingVertical: 11,
307
+ borderRadius: 12,
167
308
  backgroundColor: '#7C3AED',
309
+ shadowColor: '#7C3AED',
310
+ shadowOffset: { width: 0, height: 3 },
311
+ shadowOpacity: 0.28,
312
+ shadowRadius: 6,
313
+ elevation: 4,
168
314
  },
169
315
  allowText: {
170
316
  fontSize: 13,
171
317
  fontWeight: '700',
172
318
  color: '#FFFFFF',
319
+ ...fontStack,
173
320
  },
174
321
  });
175
322
  export default TelemetryConsentModal;
@@ -1 +1 @@
1
- export declare const LIB_VERSION = "2.0.2";
1
+ export declare const LIB_VERSION = "2.0.4";
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED FILE — do not edit by hand.
2
2
  // Regenerated from package.json on every build by scripts/gen-version.js.
3
- export const LIB_VERSION = '2.0.2';
3
+ export const LIB_VERSION = '2.0.4';
@@ -13,8 +13,8 @@ import { LIB_VERSION } from '../constants';
13
13
  import { getNativeStorageItem, setNativeStorageItem, isNativeModuleAvailable, getNativeDeviceMetrics, } from '../native/NativeInspector';
14
14
  // ─── GA4 Measurement Protocol Configuration ──────────────────────────────────
15
15
  // Automatically replaced at build-time from .env by scripts/inject-telemetry.js
16
- export const GA4_MEASUREMENT_ID = 'G-3QGMQVZX5V';
17
- export const GA4_API_SECRET = 'C46RQZ3PTfmHDnLnvU3KIg';
16
+ export const GA4_MEASUREMENT_ID = 'G-XXXXXXXXXX';
17
+ export const GA4_API_SECRET = 'YOUR_GA4_API_SECRET';
18
18
  const GA4_ENDPOINT = 'https://www.google-analytics.com/mp/collect';
19
19
  const CLIENT_ID_KEY = 'telemetry_client_id';
20
20
  // Stable session ID created once per JavaScript runtime instance
@@ -236,9 +236,9 @@ export async function trackTelemetryEvent(eventName, params = {}, options) {
236
236
  return;
237
237
  // Don't send if credentials haven't been configured yet
238
238
  if (!GA4_MEASUREMENT_ID ||
239
- GA4_MEASUREMENT_ID === 'G-3QGMQVZX5V' ||
239
+ GA4_MEASUREMENT_ID === 'G-XXXXXXXXXX' ||
240
240
  !GA4_API_SECRET ||
241
- GA4_API_SECRET === 'C46RQZ3PTfmHDnLnvU3KIg') {
241
+ GA4_API_SECRET === 'YOUR_GA4_API_SECRET') {
242
242
  return;
243
243
  }
244
244
  try {