react-native-inapp-inspector 2.0.2 → 2.0.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.
- 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
|
@@ -44,7 +44,23 @@ const AppHeaderLogo = ({ size = 46, customIcon, }) => {
|
|
|
44
44
|
const [loadError, setLoadError] = (0, react_1.useState)(false);
|
|
45
45
|
// 1. If customIcon is explicitly provided, render it directly edge-to-edge
|
|
46
46
|
if (customIcon) {
|
|
47
|
-
|
|
47
|
+
if (react_1.default.isValidElement(customIcon)) {
|
|
48
|
+
const clonedIcon = react_1.default.cloneElement(customIcon, {
|
|
49
|
+
size,
|
|
50
|
+
width: size,
|
|
51
|
+
height: size,
|
|
52
|
+
});
|
|
53
|
+
return (<react_native_1.View style={[
|
|
54
|
+
logoStyles.container,
|
|
55
|
+
{ width: size, height: size, padding: 0, borderRadius: Math.round(size * 0.28) },
|
|
56
|
+
]}>
|
|
57
|
+
{clonedIcon}
|
|
58
|
+
</react_native_1.View>);
|
|
59
|
+
}
|
|
60
|
+
return (<react_native_1.View style={[
|
|
61
|
+
logoStyles.container,
|
|
62
|
+
{ width: size, height: size, borderRadius: Math.round(size * 0.28) },
|
|
63
|
+
]}>
|
|
48
64
|
<react_native_1.Image source={customIcon} style={logoStyles.image} resizeMode="cover"/>
|
|
49
65
|
</react_native_1.View>);
|
|
50
66
|
}
|
|
@@ -60,7 +76,10 @@ const AppHeaderLogo = ({ size = 46, customIcon, }) => {
|
|
|
60
76
|
</react_native_1.View>);
|
|
61
77
|
}
|
|
62
78
|
// 3. Fallback: Inspector's Signature Owl Brand Logo
|
|
63
|
-
return (<react_native_1.View style={[
|
|
79
|
+
return (<react_native_1.View style={[
|
|
80
|
+
logoStyles.container,
|
|
81
|
+
{ width: size, height: size, padding: 0, borderRadius: Math.round(size * 0.28) },
|
|
82
|
+
]}>
|
|
64
83
|
<BrandSquareIcon_1.default size={size}/>
|
|
65
84
|
</react_native_1.View>);
|
|
66
85
|
};
|
|
@@ -48,9 +48,35 @@ const AppFonts_1 = require("../../styles/AppFonts");
|
|
|
48
48
|
const constants_1 = require("../../constants");
|
|
49
49
|
const constants_2 = require("../../constants");
|
|
50
50
|
const helpers_1 = require("../../helpers");
|
|
51
|
+
const telemetry_1 = require("../../helpers/telemetry");
|
|
51
52
|
const NetworkIcons_1 = require("../NetworkIcons");
|
|
52
53
|
const InspectorHeader = react_1.default.memo(() => {
|
|
53
|
-
const { modalHeightPercent, appIcon, selected, setSelected, selectedEvent, setSelectedEvent, selectedLog, setSelectedLog, selectedReduxSlice, setSelectedReduxSlice, selectedReduxAction, setSelectedReduxAction, reduxState, reduxLastActionMap, showHeaderInfo, setShowHeaderInfo, updateAvailable, latestNpmVersion, clearAnim, activePulseAnim, unreadPulseAnim, runClearAllWithAnimation, settingsPage, setSettingsPage, resetToDefaults, closeModal, detailTitle, activeTab, environment, selectedCrash, setSelectedCrash, } = (0, InspectorContext_1.useInspector)();
|
|
54
|
+
const { modalHeightPercent, appIcon, selected, setSelected, selectedEvent, setSelectedEvent, selectedLog, setSelectedLog, selectedReduxSlice, setSelectedReduxSlice, selectedReduxAction, setSelectedReduxAction, reduxState, reduxLastActionMap, showHeaderInfo, setShowHeaderInfo, updateAvailable, latestNpmVersion, clearAnim, activePulseAnim, unreadPulseAnim, runClearAllWithAnimation, settingsPage, setSettingsPage, resetToDefaults, closeModal, detailTitle, activeTab, environment, visible, selectedCrash, setSelectedCrash, } = (0, InspectorContext_1.useInspector)();
|
|
55
|
+
const [isTelemetryActive, setIsTelemetryActive] = react_1.default.useState(false);
|
|
56
|
+
const telemetryPulseAnim = react_1.default.useRef(new react_native_1.Animated.Value(1)).current;
|
|
57
|
+
react_1.default.useEffect(() => {
|
|
58
|
+
(0, telemetry_1.getTelemetryConsentStatus)().then(status => {
|
|
59
|
+
setIsTelemetryActive(status === 'granted');
|
|
60
|
+
});
|
|
61
|
+
}, [visible]);
|
|
62
|
+
react_1.default.useEffect(() => {
|
|
63
|
+
if (!isTelemetryActive)
|
|
64
|
+
return;
|
|
65
|
+
const pulse = react_native_1.Animated.loop(react_native_1.Animated.sequence([
|
|
66
|
+
react_native_1.Animated.timing(telemetryPulseAnim, {
|
|
67
|
+
toValue: 2.2,
|
|
68
|
+
duration: 1500,
|
|
69
|
+
useNativeDriver: true,
|
|
70
|
+
}),
|
|
71
|
+
react_native_1.Animated.timing(telemetryPulseAnim, {
|
|
72
|
+
toValue: 1,
|
|
73
|
+
duration: 0,
|
|
74
|
+
useNativeDriver: true,
|
|
75
|
+
}),
|
|
76
|
+
]));
|
|
77
|
+
pulse.start();
|
|
78
|
+
return () => pulse.stop();
|
|
79
|
+
}, [isTelemetryActive, telemetryPulseAnim]);
|
|
54
80
|
const envConfig = (0, react_1.useMemo)(() => {
|
|
55
81
|
const rawEnv = (environment || (__DEV__ ? 'DEV' : 'PROD')).trim();
|
|
56
82
|
const clean = rawEnv.toUpperCase();
|
|
@@ -213,7 +239,7 @@ const InspectorHeader = react_1.default.memo(() => {
|
|
|
213
239
|
minWidth: 0,
|
|
214
240
|
marginRight: 6,
|
|
215
241
|
}}>
|
|
216
|
-
<AppHeaderLogo_1.default size={
|
|
242
|
+
<AppHeaderLogo_1.default size={46} customIcon={appIcon}/>
|
|
217
243
|
<react_native_1.View style={{ gap: 2.5, flex: 1, minWidth: 0 }}>
|
|
218
244
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, minWidth: 0 }}>
|
|
219
245
|
<react_native_1.Text style={[styles_1.default.headerTitle, { flexShrink: 1 }]} numberOfLines={1} ellipsizeMode="tail">
|
|
@@ -260,11 +286,11 @@ const InspectorHeader = react_1.default.memo(() => {
|
|
|
260
286
|
</react_native_1.Pressable>)}
|
|
261
287
|
</react_native_1.View>
|
|
262
288
|
|
|
263
|
-
{/*
|
|
289
|
+
{/* OS & NPM Version Representation */}
|
|
264
290
|
<react_native_1.View style={{
|
|
265
291
|
flexDirection: 'row',
|
|
266
292
|
alignItems: 'center',
|
|
267
|
-
gap:
|
|
293
|
+
gap: 5,
|
|
268
294
|
minWidth: 0,
|
|
269
295
|
}}>
|
|
270
296
|
<react_native_1.View style={{
|
|
@@ -274,21 +300,21 @@ const InspectorHeader = react_1.default.memo(() => {
|
|
|
274
300
|
borderRadius: 5,
|
|
275
301
|
paddingHorizontal: 6,
|
|
276
302
|
paddingVertical: 2,
|
|
277
|
-
gap:
|
|
303
|
+
gap: 4,
|
|
278
304
|
borderWidth: 1,
|
|
279
305
|
borderColor: `${AppColors_1.AppColors.white}2E`,
|
|
280
|
-
flexShrink:
|
|
281
|
-
minWidth: 0,
|
|
306
|
+
flexShrink: 0,
|
|
282
307
|
}}>
|
|
283
|
-
{react_native_1.Platform.OS === 'ios' ? (<NetworkIcons_1.AppleIcon color={`${AppColors_1.AppColors.white}
|
|
308
|
+
{react_native_1.Platform.OS === 'ios' ? (<NetworkIcons_1.AppleIcon color={`${AppColors_1.AppColors.white}E6`} size={10}/>) : (<NetworkIcons_1.AndroidIcon color={`${AppColors_1.AppColors.white}E6`} size={10}/>)}
|
|
284
309
|
<react_native_1.Text style={{
|
|
285
310
|
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
286
311
|
fontSize: 9.5,
|
|
287
312
|
color: `${AppColors_1.AppColors.white}EB`,
|
|
288
313
|
letterSpacing: 0.1,
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
314
|
+
}} numberOfLines={1}>
|
|
315
|
+
{react_native_1.Platform.OS === 'ios'
|
|
316
|
+
? `iOS ${react_native_1.Platform.Version}`
|
|
317
|
+
: `Android ${react_native_1.Platform.Version}`}
|
|
292
318
|
</react_native_1.Text>
|
|
293
319
|
</react_native_1.View>
|
|
294
320
|
|
|
@@ -317,6 +343,53 @@ const InspectorHeader = react_1.default.memo(() => {
|
|
|
317
343
|
v{constants_2.LIB_VERSION}
|
|
318
344
|
</react_native_1.Text>
|
|
319
345
|
</react_native_1.Pressable>
|
|
346
|
+
|
|
347
|
+
{isTelemetryActive && (<react_native_1.Pressable onPress={() => react_native_1.Alert.alert('Anonymous Telemetry Active', 'Anonymous diagnostics (such as React Native version, JavaScript engine, and device model) are currently enabled to help improve library tooling.\n\nNo user data or network payloads are captured. You can toggle this anytime in Settings.', [{ text: 'Got it' }])} style={{
|
|
348
|
+
flexDirection: 'row',
|
|
349
|
+
alignItems: 'center',
|
|
350
|
+
backgroundColor: 'rgba(16, 185, 129, 0.22)',
|
|
351
|
+
borderRadius: 5,
|
|
352
|
+
paddingHorizontal: 5.5,
|
|
353
|
+
paddingVertical: 2,
|
|
354
|
+
gap: 4.5,
|
|
355
|
+
borderWidth: 1,
|
|
356
|
+
borderColor: 'rgba(52, 211, 153, 0.45)',
|
|
357
|
+
flexShrink: 0,
|
|
358
|
+
}}>
|
|
359
|
+
<react_native_1.View style={{
|
|
360
|
+
width: 6,
|
|
361
|
+
height: 6,
|
|
362
|
+
alignItems: 'center',
|
|
363
|
+
justifyContent: 'center',
|
|
364
|
+
}}>
|
|
365
|
+
<react_native_1.Animated.View style={{
|
|
366
|
+
position: 'absolute',
|
|
367
|
+
width: 6,
|
|
368
|
+
height: 6,
|
|
369
|
+
borderRadius: 3,
|
|
370
|
+
backgroundColor: '#34D399',
|
|
371
|
+
opacity: telemetryPulseAnim.interpolate({
|
|
372
|
+
inputRange: [1, 2.2],
|
|
373
|
+
outputRange: [0.8, 0],
|
|
374
|
+
}),
|
|
375
|
+
transform: [{ scale: telemetryPulseAnim }],
|
|
376
|
+
}}/>
|
|
377
|
+
<react_native_1.View style={{
|
|
378
|
+
width: 4,
|
|
379
|
+
height: 4,
|
|
380
|
+
borderRadius: 2,
|
|
381
|
+
backgroundColor: '#10B981',
|
|
382
|
+
}}/>
|
|
383
|
+
</react_native_1.View>
|
|
384
|
+
<react_native_1.Text style={{
|
|
385
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
386
|
+
fontSize: 9,
|
|
387
|
+
color: '#6EE7B7',
|
|
388
|
+
letterSpacing: 0.2,
|
|
389
|
+
}}>
|
|
390
|
+
LIVE
|
|
391
|
+
</react_native_1.Text>
|
|
392
|
+
</react_native_1.Pressable>)}
|
|
320
393
|
</react_native_1.View>
|
|
321
394
|
</react_native_1.View>
|
|
322
395
|
</react_native_1.View>) : null}
|
|
@@ -57,6 +57,7 @@ const CrashTab_1 = __importDefault(require("./CrashTab"));
|
|
|
57
57
|
const CrashDetail_1 = __importDefault(require("./CrashDetail"));
|
|
58
58
|
const SettingsPanel_1 = __importDefault(require("./SettingsPanel"));
|
|
59
59
|
const TelemetryConsentModal_1 = __importDefault(require("./TelemetryConsentModal"));
|
|
60
|
+
const NpmUpdateToast_1 = __importDefault(require("./NpmUpdateToast"));
|
|
60
61
|
const Toast_1 = __importDefault(require("../Toast"));
|
|
61
62
|
const styles_1 = __importDefault(require("../../styles"));
|
|
62
63
|
const AppColors_1 = require("../../styles/AppColors");
|
|
@@ -206,13 +207,16 @@ const MainScreen = () => {
|
|
|
206
207
|
{/* Bottom floating toast notification */}
|
|
207
208
|
<Toast_1.default />
|
|
208
209
|
|
|
209
|
-
{/*
|
|
210
|
-
<
|
|
210
|
+
{/* NPM Version Update Toast with timeout progress bar */}
|
|
211
|
+
<NpmUpdateToast_1.default />
|
|
211
212
|
</react_native_1.View>
|
|
212
213
|
</react_native_1.View>
|
|
213
214
|
</ErrorBoundary_1.default>)}
|
|
214
215
|
{hasNavigationContext && (<NavigationTracker_1.default onStateChange={setNavState}/>)}
|
|
215
216
|
</react_native_1.Modal>
|
|
217
|
+
|
|
218
|
+
{/* Anonymous Telemetry Consent Dialog at root viewport */}
|
|
219
|
+
<TelemetryConsentModal_1.default />
|
|
216
220
|
</>);
|
|
217
221
|
};
|
|
218
222
|
exports.default = MainScreen;
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.NpmUpdateToast = void 0;
|
|
37
|
+
const react_1 = __importStar(require("react"));
|
|
38
|
+
const react_native_1 = require("react-native");
|
|
39
|
+
const react_native_svg_1 = __importStar(require("react-native-svg"));
|
|
40
|
+
const InspectorContext_1 = require("./InspectorContext");
|
|
41
|
+
const constants_1 = require("../../constants");
|
|
42
|
+
const NetworkIcons_1 = require("../NetworkIcons");
|
|
43
|
+
const CloseSvg = ({ size = 13, color = '#94A3B8' }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
44
|
+
<react_native_svg_1.Path d="M18 6L6 18M6 6l12 12" stroke={color} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"/>
|
|
45
|
+
</react_native_svg_1.default>);
|
|
46
|
+
const ExternalLinkSvg = ({ size = 12, color = '#FFFFFF' }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
47
|
+
<react_native_svg_1.Path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
48
|
+
<react_native_svg_1.Path d="M15 3h6v6" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
49
|
+
<react_native_svg_1.Path d="M10 14L21 3" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
50
|
+
</react_native_svg_1.default>);
|
|
51
|
+
const TOAST_TIMEOUT_MS = 6500;
|
|
52
|
+
const NpmUpdateToast = () => {
|
|
53
|
+
const { updateAvailable, latestNpmVersion, showUpdateToast } = (0, InspectorContext_1.useInspector)();
|
|
54
|
+
const [dismissed, setDismissed] = (0, react_1.useState)(false);
|
|
55
|
+
const [visible, setVisible] = (0, react_1.useState)(false);
|
|
56
|
+
const translateYAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(50)).current;
|
|
57
|
+
const opacityAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
|
|
58
|
+
const progressAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
|
|
59
|
+
const timerRef = (0, react_1.useRef)(null);
|
|
60
|
+
(0, react_1.useEffect)(() => {
|
|
61
|
+
if (showUpdateToast && updateAvailable && latestNpmVersion && !dismissed) {
|
|
62
|
+
setVisible(true);
|
|
63
|
+
// Slide and fade in
|
|
64
|
+
react_native_1.Animated.parallel([
|
|
65
|
+
react_native_1.Animated.spring(translateYAnim, {
|
|
66
|
+
toValue: 0,
|
|
67
|
+
friction: 8,
|
|
68
|
+
tension: 40,
|
|
69
|
+
useNativeDriver: true,
|
|
70
|
+
}),
|
|
71
|
+
react_native_1.Animated.timing(opacityAnim, {
|
|
72
|
+
toValue: 1,
|
|
73
|
+
duration: 250,
|
|
74
|
+
useNativeDriver: true,
|
|
75
|
+
}),
|
|
76
|
+
]).start();
|
|
77
|
+
// Progress bar countdown from 1 to 0
|
|
78
|
+
progressAnim.setValue(1);
|
|
79
|
+
react_native_1.Animated.timing(progressAnim, {
|
|
80
|
+
toValue: 0,
|
|
81
|
+
duration: TOAST_TIMEOUT_MS,
|
|
82
|
+
useNativeDriver: false,
|
|
83
|
+
}).start();
|
|
84
|
+
// Auto-hide after timeout
|
|
85
|
+
timerRef.current = setTimeout(() => {
|
|
86
|
+
handleDismiss();
|
|
87
|
+
}, TOAST_TIMEOUT_MS);
|
|
88
|
+
}
|
|
89
|
+
return () => {
|
|
90
|
+
if (timerRef.current) {
|
|
91
|
+
clearTimeout(timerRef.current);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}, [showUpdateToast, updateAvailable, latestNpmVersion, dismissed]);
|
|
95
|
+
const handleDismiss = () => {
|
|
96
|
+
react_native_1.Animated.parallel([
|
|
97
|
+
react_native_1.Animated.timing(opacityAnim, {
|
|
98
|
+
toValue: 0,
|
|
99
|
+
duration: 200,
|
|
100
|
+
useNativeDriver: true,
|
|
101
|
+
}),
|
|
102
|
+
react_native_1.Animated.timing(translateYAnim, {
|
|
103
|
+
toValue: 50,
|
|
104
|
+
duration: 200,
|
|
105
|
+
useNativeDriver: true,
|
|
106
|
+
}),
|
|
107
|
+
]).start(() => {
|
|
108
|
+
setVisible(false);
|
|
109
|
+
setDismissed(true);
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
const handleOpenNpm = () => {
|
|
113
|
+
react_native_1.Linking.openURL('https://www.npmjs.com/package/react-native-inapp-inspector').catch(() => { });
|
|
114
|
+
handleDismiss();
|
|
115
|
+
};
|
|
116
|
+
if (!showUpdateToast || !visible || !updateAvailable || !latestNpmVersion)
|
|
117
|
+
return null;
|
|
118
|
+
const progressWidth = progressAnim.interpolate({
|
|
119
|
+
inputRange: [0, 1],
|
|
120
|
+
outputRange: ['0%', '100%'],
|
|
121
|
+
});
|
|
122
|
+
return (<react_native_1.Animated.View style={[
|
|
123
|
+
styles.container,
|
|
124
|
+
{
|
|
125
|
+
opacity: opacityAnim,
|
|
126
|
+
transform: [{ translateY: translateYAnim }],
|
|
127
|
+
},
|
|
128
|
+
]}>
|
|
129
|
+
<react_native_1.View style={styles.contentRow}>
|
|
130
|
+
{/* Left NPM Badge Icon */}
|
|
131
|
+
<react_native_1.View style={styles.npmIconContainer}>
|
|
132
|
+
<NetworkIcons_1.NpmIcon size={14} color="#CB3837"/>
|
|
133
|
+
</react_native_1.View>
|
|
134
|
+
|
|
135
|
+
{/* Text Details */}
|
|
136
|
+
<react_native_1.View style={styles.textContainer}>
|
|
137
|
+
<react_native_1.View style={styles.titleRow}>
|
|
138
|
+
<react_native_1.Text style={styles.titleText}>Update Available</react_native_1.Text>
|
|
139
|
+
<react_native_1.View style={styles.versionPill}>
|
|
140
|
+
<react_native_1.Text style={styles.versionPillText}>v{latestNpmVersion}</react_native_1.Text>
|
|
141
|
+
</react_native_1.View>
|
|
142
|
+
</react_native_1.View>
|
|
143
|
+
<react_native_1.Text style={styles.subtitleText} numberOfLines={1}>
|
|
144
|
+
Installed: v{constants_1.LIB_VERSION} • New version is ready
|
|
145
|
+
</react_native_1.Text>
|
|
146
|
+
</react_native_1.View>
|
|
147
|
+
|
|
148
|
+
{/* Action Button: View */}
|
|
149
|
+
<react_native_1.TouchableOpacity style={styles.actionButton} onPress={handleOpenNpm} activeOpacity={0.8}>
|
|
150
|
+
<react_native_1.Text style={styles.actionButtonText}>View</react_native_1.Text>
|
|
151
|
+
<ExternalLinkSvg size={10} color="#FFFFFF"/>
|
|
152
|
+
</react_native_1.TouchableOpacity>
|
|
153
|
+
|
|
154
|
+
{/* Close Button */}
|
|
155
|
+
<react_native_1.TouchableOpacity style={styles.closeButton} onPress={handleDismiss} hitSlop={8} activeOpacity={0.7}>
|
|
156
|
+
<CloseSvg size={12} color="#94A3B8"/>
|
|
157
|
+
</react_native_1.TouchableOpacity>
|
|
158
|
+
</react_native_1.View>
|
|
159
|
+
|
|
160
|
+
{/* Animated Linear Timeout Progress Bar */}
|
|
161
|
+
<react_native_1.View style={styles.progressBarTrack}>
|
|
162
|
+
<react_native_1.Animated.View style={[styles.progressBarFill, { width: progressWidth }]}/>
|
|
163
|
+
</react_native_1.View>
|
|
164
|
+
</react_native_1.Animated.View>);
|
|
165
|
+
};
|
|
166
|
+
exports.NpmUpdateToast = NpmUpdateToast;
|
|
167
|
+
const fontStack = react_native_1.Platform.select({
|
|
168
|
+
ios: {
|
|
169
|
+
fontFamily: 'System',
|
|
170
|
+
},
|
|
171
|
+
android: {
|
|
172
|
+
fontFamily: 'sans-serif',
|
|
173
|
+
},
|
|
174
|
+
default: {},
|
|
175
|
+
});
|
|
176
|
+
const styles = react_native_1.StyleSheet.create({
|
|
177
|
+
container: {
|
|
178
|
+
position: 'absolute',
|
|
179
|
+
bottom: 24,
|
|
180
|
+
left: 16,
|
|
181
|
+
right: 16,
|
|
182
|
+
backgroundColor: '#0F172A',
|
|
183
|
+
borderRadius: 16,
|
|
184
|
+
borderWidth: 1,
|
|
185
|
+
borderColor: '#334155',
|
|
186
|
+
shadowColor: '#000000',
|
|
187
|
+
shadowOffset: { width: 0, height: 10 },
|
|
188
|
+
shadowOpacity: 0.35,
|
|
189
|
+
shadowRadius: 20,
|
|
190
|
+
elevation: 20,
|
|
191
|
+
overflow: 'hidden',
|
|
192
|
+
zIndex: 99999,
|
|
193
|
+
},
|
|
194
|
+
contentRow: {
|
|
195
|
+
flexDirection: 'row',
|
|
196
|
+
alignItems: 'center',
|
|
197
|
+
paddingVertical: 12,
|
|
198
|
+
paddingHorizontal: 14,
|
|
199
|
+
gap: 10,
|
|
200
|
+
},
|
|
201
|
+
npmIconContainer: {
|
|
202
|
+
width: 32,
|
|
203
|
+
height: 32,
|
|
204
|
+
borderRadius: 10,
|
|
205
|
+
backgroundColor: '#FFFFFF',
|
|
206
|
+
justifyContent: 'center',
|
|
207
|
+
alignItems: 'center',
|
|
208
|
+
borderWidth: 1,
|
|
209
|
+
borderColor: '#CBD5E1',
|
|
210
|
+
flexShrink: 0,
|
|
211
|
+
},
|
|
212
|
+
textContainer: {
|
|
213
|
+
flex: 1,
|
|
214
|
+
minWidth: 0,
|
|
215
|
+
},
|
|
216
|
+
titleRow: {
|
|
217
|
+
flexDirection: 'row',
|
|
218
|
+
alignItems: 'center',
|
|
219
|
+
gap: 6,
|
|
220
|
+
},
|
|
221
|
+
titleText: {
|
|
222
|
+
fontSize: 13,
|
|
223
|
+
fontWeight: '700',
|
|
224
|
+
color: '#F8FAFC',
|
|
225
|
+
letterSpacing: -0.2,
|
|
226
|
+
...fontStack,
|
|
227
|
+
},
|
|
228
|
+
versionPill: {
|
|
229
|
+
backgroundColor: '#7C3AED26',
|
|
230
|
+
paddingHorizontal: 6,
|
|
231
|
+
paddingVertical: 1.5,
|
|
232
|
+
borderRadius: 6,
|
|
233
|
+
borderWidth: 1,
|
|
234
|
+
borderColor: '#7C3AED59',
|
|
235
|
+
},
|
|
236
|
+
versionPillText: {
|
|
237
|
+
fontSize: 10.5,
|
|
238
|
+
fontWeight: '700',
|
|
239
|
+
color: '#A78BFA',
|
|
240
|
+
...fontStack,
|
|
241
|
+
},
|
|
242
|
+
subtitleText: {
|
|
243
|
+
fontSize: 11,
|
|
244
|
+
color: '#94A3B8',
|
|
245
|
+
marginTop: 1.5,
|
|
246
|
+
...fontStack,
|
|
247
|
+
},
|
|
248
|
+
actionButton: {
|
|
249
|
+
flexDirection: 'row',
|
|
250
|
+
alignItems: 'center',
|
|
251
|
+
gap: 4,
|
|
252
|
+
backgroundColor: '#7C3AED',
|
|
253
|
+
paddingVertical: 6,
|
|
254
|
+
paddingHorizontal: 10,
|
|
255
|
+
borderRadius: 8,
|
|
256
|
+
flexShrink: 0,
|
|
257
|
+
shadowColor: '#7C3AED',
|
|
258
|
+
shadowOffset: { width: 0, height: 2 },
|
|
259
|
+
shadowOpacity: 0.3,
|
|
260
|
+
shadowRadius: 4,
|
|
261
|
+
elevation: 3,
|
|
262
|
+
},
|
|
263
|
+
actionButtonText: {
|
|
264
|
+
fontSize: 11.5,
|
|
265
|
+
fontWeight: '700',
|
|
266
|
+
color: '#FFFFFF',
|
|
267
|
+
...fontStack,
|
|
268
|
+
},
|
|
269
|
+
closeButton: {
|
|
270
|
+
width: 24,
|
|
271
|
+
height: 24,
|
|
272
|
+
borderRadius: 12,
|
|
273
|
+
backgroundColor: '#1E293B',
|
|
274
|
+
justifyContent: 'center',
|
|
275
|
+
alignItems: 'center',
|
|
276
|
+
flexShrink: 0,
|
|
277
|
+
},
|
|
278
|
+
progressBarTrack: {
|
|
279
|
+
height: 3,
|
|
280
|
+
width: '100%',
|
|
281
|
+
backgroundColor: '#1E293B',
|
|
282
|
+
},
|
|
283
|
+
progressBarFill: {
|
|
284
|
+
height: '100%',
|
|
285
|
+
backgroundColor: '#7C3AED',
|
|
286
|
+
},
|
|
287
|
+
});
|
|
288
|
+
exports.default = exports.NpmUpdateToast;
|