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.
- package/dist/commonjs/components/AppHeaderLogo.js +21 -2
- package/dist/commonjs/components/Inspector/InspectorHeader.js +84 -11
- package/dist/commonjs/components/Inspector/MainScreen.js +6 -2
- package/dist/commonjs/components/Inspector/NpmUpdateToast.d.ts +3 -0
- package/dist/commonjs/components/Inspector/NpmUpdateToast.js +288 -0
- package/dist/commonjs/components/Inspector/SettingsPanel.js +192 -1
- package/dist/commonjs/components/Inspector/TelemetryConsentModal.js +218 -71
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/helpers/telemetry.js +4 -4
- package/dist/commonjs/index.js +14 -2
- package/dist/commonjs/types/interfaces.d.ts +5 -0
- package/dist/esm/components/AppHeaderLogo.js +21 -2
- package/dist/esm/components/Inspector/InspectorHeader.js +85 -12
- package/dist/esm/components/Inspector/MainScreen.js +6 -2
- package/dist/esm/components/Inspector/NpmUpdateToast.d.ts +3 -0
- package/dist/esm/components/Inspector/NpmUpdateToast.js +251 -0
- package/dist/esm/components/Inspector/SettingsPanel.js +192 -1
- package/dist/esm/components/Inspector/TelemetryConsentModal.js +219 -72
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/helpers/telemetry.js +4 -4
- package/dist/esm/index.js +14 -2
- package/dist/esm/types/interfaces.d.ts +5 -0
- package/package.json +1 -1
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/8.9/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/9.2.0/checksums/checksums.lock +0 -0
- package/android/.gradle/9.2.0/fileChanges/last-build.bin +0 -0
- package/android/.gradle/9.2.0/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/9.2.0/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
- package/android/.gradle/vcs-1/gc.properties +0 -0
- 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 {
|
|
4
|
-
import {
|
|
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.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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={[
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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.
|
|
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(
|
|
146
|
+
backgroundColor: 'rgba(15, 23, 42, 0.56)',
|
|
85
147
|
justifyContent: 'center',
|
|
86
148
|
alignItems: 'center',
|
|
87
|
-
|
|
149
|
+
paddingHorizontal: 20,
|
|
88
150
|
zIndex: 999999,
|
|
89
151
|
},
|
|
90
152
|
card: {
|
|
91
153
|
width: '100%',
|
|
92
|
-
maxWidth:
|
|
93
|
-
backgroundColor: '#
|
|
94
|
-
borderRadius:
|
|
95
|
-
padding: 22,
|
|
154
|
+
maxWidth: 356,
|
|
155
|
+
backgroundColor: '#FFFFFF',
|
|
156
|
+
borderRadius: 24,
|
|
96
157
|
borderWidth: 1,
|
|
97
|
-
borderColor: '
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
105
|
-
|
|
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
|
-
|
|
179
|
+
borderWidth: 1,
|
|
180
|
+
borderColor: '#E2E8F0',
|
|
181
|
+
zIndex: 10,
|
|
108
182
|
},
|
|
109
|
-
|
|
110
|
-
|
|
183
|
+
headerSection: {
|
|
184
|
+
alignItems: 'center',
|
|
185
|
+
width: '100%',
|
|
186
|
+
marginBottom: 4,
|
|
111
187
|
},
|
|
112
|
-
|
|
113
|
-
|
|
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: '
|
|
118
|
-
color: '#
|
|
119
|
-
letterSpacing: -0.
|
|
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:
|
|
123
|
-
color: AppColors.purple || '#9055FF',
|
|
215
|
+
fontSize: 11.5,
|
|
124
216
|
fontWeight: '600',
|
|
125
|
-
|
|
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:
|
|
129
|
-
lineHeight:
|
|
130
|
-
color: '
|
|
131
|
-
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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: '
|
|
139
|
-
marginBottom:
|
|
256
|
+
borderColor: '#E2E8F0',
|
|
257
|
+
marginBottom: 14,
|
|
258
|
+
width: '100%',
|
|
259
|
+
},
|
|
260
|
+
privacyShieldWrapper: {
|
|
261
|
+
marginRight: 7,
|
|
262
|
+
marginTop: 1,
|
|
140
263
|
},
|
|
141
264
|
privacyText: {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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: '
|
|
277
|
+
justifyContent: 'space-between',
|
|
149
278
|
alignItems: 'center',
|
|
150
|
-
gap:
|
|
279
|
+
gap: 10,
|
|
280
|
+
width: '100%',
|
|
151
281
|
},
|
|
152
282
|
declineButton: {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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: '
|
|
297
|
+
color: '#475569',
|
|
298
|
+
...fontStack,
|
|
162
299
|
},
|
|
163
300
|
allowButton: {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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.
|
|
1
|
+
export declare 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-
|
|
17
|
-
export const GA4_API_SECRET = '
|
|
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-
|
|
239
|
+
GA4_MEASUREMENT_ID === 'G-XXXXXXXXXX' ||
|
|
240
240
|
!GA4_API_SECRET ||
|
|
241
|
-
GA4_API_SECRET === '
|
|
241
|
+
GA4_API_SECRET === 'YOUR_GA4_API_SECRET') {
|
|
242
242
|
return;
|
|
243
243
|
}
|
|
244
244
|
try {
|