react-native-inapp-inspector 1.1.24 → 1.1.26
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/android/build.gradle +36 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.java +114 -0
- package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.java +28 -0
- package/dist/commonjs/components/AnalyticsEventCard.js +94 -88
- package/dist/commonjs/components/ConsoleLogCard.js +49 -25
- package/dist/commonjs/components/ErrorBoundary.d.ts +1 -1
- package/dist/commonjs/components/ErrorBoundary.js +9 -145
- package/dist/commonjs/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
- package/dist/commonjs/components/Inspector/AnalyticsFilterModal.js +1002 -0
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +637 -10
- package/dist/commonjs/components/Inspector/BundleTab.d.ts +1 -1
- package/dist/commonjs/components/Inspector/BundleTab.js +826 -406
- package/dist/commonjs/components/Inspector/CrashDetail.d.ts +3 -0
- package/dist/commonjs/components/Inspector/CrashDetail.js +796 -0
- package/dist/commonjs/components/Inspector/CrashFilterModal.d.ts +20 -0
- package/dist/commonjs/components/Inspector/CrashFilterModal.js +597 -0
- package/dist/commonjs/components/Inspector/CrashTab.d.ts +3 -0
- package/dist/commonjs/components/Inspector/CrashTab.js +727 -0
- package/dist/commonjs/components/Inspector/InspectorContext.js +6 -1
- package/dist/commonjs/components/Inspector/InspectorHeader.js +65 -28
- package/dist/commonjs/components/Inspector/LogDetail.js +227 -114
- package/dist/commonjs/components/Inspector/MainScreen.js +13 -4
- package/dist/commonjs/components/Inspector/NetworkDetail.js +131 -81
- package/dist/commonjs/components/Inspector/PerformanceTab.js +20 -10
- package/dist/commonjs/components/Inspector/SettingsPanel.js +90 -1
- package/dist/commonjs/components/Inspector/TabBar.js +15 -3
- package/dist/commonjs/components/NetworkIcons.d.ts +25 -0
- package/dist/commonjs/components/NetworkIcons.js +188 -1
- package/dist/commonjs/components/SegmentedTabs.js +33 -23
- package/dist/commonjs/components/TreeNode.js +13 -12
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/analyticsLogger.js +70 -44
- package/dist/commonjs/customHooks/bundleAnalyzer.d.ts +5 -1
- package/dist/commonjs/customHooks/bundleAnalyzer.js +497 -126
- package/dist/commonjs/customHooks/consoleLogger.d.ts +1 -0
- package/dist/commonjs/customHooks/consoleLogger.js +153 -51
- package/dist/commonjs/customHooks/crashHandler.d.ts +64 -0
- package/dist/commonjs/customHooks/crashHandler.js +681 -0
- package/dist/commonjs/customHooks/networkLogger.js +74 -49
- package/dist/commonjs/customHooks/performanceTracker.d.ts +8 -0
- package/dist/commonjs/customHooks/performanceTracker.js +44 -3
- package/dist/commonjs/decorators/index.d.ts +49 -0
- package/dist/commonjs/decorators/index.js +142 -0
- package/dist/commonjs/helpers/gaAnalyticsRegistry.d.ts +18 -0
- package/dist/commonjs/helpers/gaAnalyticsRegistry.js +174 -0
- package/dist/commonjs/helpers/index.d.ts +7 -4
- package/dist/commonjs/helpers/index.js +102 -64
- package/dist/commonjs/i18n/locales/en.json +182 -4
- package/dist/commonjs/index.d.ts +6 -0
- package/dist/commonjs/index.js +310 -8
- package/dist/commonjs/styles/index.d.ts +4 -1
- package/dist/commonjs/styles/index.js +22 -19
- package/dist/commonjs/types/enums.d.ts +156 -9
- package/dist/commonjs/types/enums.js +139 -2
- package/dist/commonjs/types/interfaces.d.ts +70 -1
- package/dist/esm/components/AnalyticsEventCard.js +95 -89
- package/dist/esm/components/ConsoleLogCard.js +49 -25
- package/dist/esm/components/ErrorBoundary.d.ts +1 -1
- package/dist/esm/components/ErrorBoundary.js +10 -113
- package/dist/esm/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
- package/dist/esm/components/Inspector/AnalyticsFilterModal.js +964 -0
- package/dist/esm/components/Inspector/AnalyticsTab.js +639 -12
- package/dist/esm/components/Inspector/BundleTab.d.ts +1 -1
- package/dist/esm/components/Inspector/BundleTab.js +827 -407
- package/dist/esm/components/Inspector/CrashDetail.d.ts +3 -0
- package/dist/esm/components/Inspector/CrashDetail.js +758 -0
- package/dist/esm/components/Inspector/CrashFilterModal.d.ts +20 -0
- package/dist/esm/components/Inspector/CrashFilterModal.js +557 -0
- package/dist/esm/components/Inspector/CrashTab.d.ts +3 -0
- package/dist/esm/components/Inspector/CrashTab.js +689 -0
- package/dist/esm/components/Inspector/InspectorContext.js +1 -0
- package/dist/esm/components/Inspector/InspectorHeader.js +66 -29
- package/dist/esm/components/Inspector/LogDetail.js +227 -114
- package/dist/esm/components/Inspector/MainScreen.js +14 -5
- package/dist/esm/components/Inspector/NetworkDetail.js +132 -49
- package/dist/esm/components/Inspector/PerformanceTab.js +20 -10
- package/dist/esm/components/Inspector/SettingsPanel.js +91 -2
- package/dist/esm/components/Inspector/TabBar.js +16 -4
- package/dist/esm/components/NetworkIcons.d.ts +25 -0
- package/dist/esm/components/NetworkIcons.js +161 -0
- package/dist/esm/components/SegmentedTabs.js +33 -23
- package/dist/esm/components/TreeNode.js +13 -12
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/analyticsLogger.js +70 -44
- package/dist/esm/customHooks/bundleAnalyzer.d.ts +5 -1
- package/dist/esm/customHooks/bundleAnalyzer.js +493 -125
- package/dist/esm/customHooks/consoleLogger.d.ts +1 -0
- package/dist/esm/customHooks/consoleLogger.js +151 -50
- package/dist/esm/customHooks/crashHandler.d.ts +64 -0
- package/dist/esm/customHooks/crashHandler.js +659 -0
- package/dist/esm/customHooks/networkLogger.js +74 -49
- package/dist/esm/customHooks/performanceTracker.d.ts +8 -0
- package/dist/esm/customHooks/performanceTracker.js +38 -1
- package/dist/esm/decorators/index.d.ts +49 -0
- package/dist/esm/decorators/index.js +137 -0
- package/dist/esm/helpers/gaAnalyticsRegistry.d.ts +18 -0
- package/dist/esm/helpers/gaAnalyticsRegistry.js +169 -0
- package/dist/esm/helpers/index.d.ts +7 -4
- package/dist/esm/helpers/index.js +100 -63
- package/dist/esm/i18n/locales/en.json +182 -4
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.js +262 -8
- package/dist/esm/styles/index.d.ts +4 -1
- package/dist/esm/styles/index.js +22 -19
- package/dist/esm/types/enums.d.ts +156 -9
- package/dist/esm/types/enums.js +138 -3
- package/dist/esm/types/interfaces.d.ts +70 -1
- package/ios/NetworkInspectorModule.h +6 -0
- package/ios/NetworkInspectorModule.m +125 -0
- package/package.json +5 -2
- package/react-native-inapp-inspector.podspec +18 -0
|
@@ -285,7 +285,10 @@ const MediaPreviewThumbnail = ({ file }) => {
|
|
|
285
285
|
function buildBundleFileTree(files) {
|
|
286
286
|
const rootMap = new Map();
|
|
287
287
|
for (const file of files) {
|
|
288
|
-
const
|
|
288
|
+
const cleanPath = file.path.replace(/^\/+/, '');
|
|
289
|
+
const parts = cleanPath.split('/').filter(Boolean);
|
|
290
|
+
if (parts.length === 0)
|
|
291
|
+
continue;
|
|
289
292
|
let currentLevel = rootMap;
|
|
290
293
|
for (let i = 0; i < parts.length; i++) {
|
|
291
294
|
const part = parts[i];
|
|
@@ -339,21 +342,21 @@ function buildBundleFileTree(files) {
|
|
|
339
342
|
}
|
|
340
343
|
return convertMapToNodes(rootMap);
|
|
341
344
|
}
|
|
342
|
-
const BundleTreeNodeView = ({ node, level, search, totalBundleKb,
|
|
343
|
-
const
|
|
345
|
+
const BundleTreeNodeView = ({ node, level, search, totalBundleKb, expandedFolders, toggleFolder, isLastChild, }) => {
|
|
346
|
+
const isExpanded = search ? true : !!expandedFolders[node.fullPath];
|
|
347
|
+
const isCollapsed = !isExpanded;
|
|
348
|
+
const indentLeft = level * 16 + 10;
|
|
344
349
|
if (node.isFolder) {
|
|
345
|
-
return (<react_native_1.View style={bundleStyles.
|
|
350
|
+
return (<react_native_1.View style={bundleStyles.treeFolderBlock}>
|
|
346
351
|
<TouchableScale_1.default onPress={() => toggleFolder(node.fullPath)} style={[
|
|
347
|
-
bundleStyles.
|
|
348
|
-
{ paddingLeft:
|
|
352
|
+
bundleStyles.treeFolderRow,
|
|
353
|
+
{ paddingLeft: indentLeft },
|
|
349
354
|
]}>
|
|
350
|
-
<react_native_1.View style={
|
|
351
|
-
<react_native_1.
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
</react_native_1.View>
|
|
356
|
-
{isCollapsed ? (<NetworkIcons_1.FolderIcon color={AppColors_1.AppColors.amber500} size={16}/>) : (<NetworkIcons_1.FolderOpenIcon color={AppColors_1.AppColors.amber500} size={16}/>)}
|
|
355
|
+
<react_native_1.View style={bundleStyles.treeRowLeft}>
|
|
356
|
+
<react_native_1.Text style={bundleStyles.treeChevron}>
|
|
357
|
+
{isCollapsed ? '▸' : '▾'}
|
|
358
|
+
</react_native_1.Text>
|
|
359
|
+
{isCollapsed ? (<NetworkIcons_1.FolderIcon color={AppColors_1.AppColors.amber500} size={15}/>) : (<NetworkIcons_1.FolderOpenIcon color={AppColors_1.AppColors.amber500} size={15}/>)}
|
|
357
360
|
<HighlightText_1.default text={node.name + '/'} search={search} style={bundleStyles.treeFolderName} highlightStyle={bundleStyles.searchHighlight}/>
|
|
358
361
|
<react_native_1.View style={bundleStyles.treeCountBadge}>
|
|
359
362
|
<react_native_1.Text style={bundleStyles.treeCountBadgeText}>
|
|
@@ -362,7 +365,7 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, collapsedFolde
|
|
|
362
365
|
</react_native_1.View>
|
|
363
366
|
</react_native_1.View>
|
|
364
367
|
|
|
365
|
-
<react_native_1.View style={
|
|
368
|
+
<react_native_1.View style={bundleStyles.treeRowRight}>
|
|
366
369
|
<react_native_1.Text style={bundleStyles.treeFolderSize}>
|
|
367
370
|
{node.sizeKb >= 1024
|
|
368
371
|
? (0, i18n_1.t)('bundle.fileSizeMb', { size: (node.sizeKb / 1024).toFixed(2) })
|
|
@@ -376,8 +379,8 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, collapsedFolde
|
|
|
376
379
|
</react_native_1.View>
|
|
377
380
|
</TouchableScale_1.default>
|
|
378
381
|
|
|
379
|
-
{!isCollapsed && (<react_native_1.View style={
|
|
380
|
-
{node.children.map((child, cIdx) => (<BundleTreeNodeView key={child.id} node={child} level={level + 1} search={search} totalBundleKb={totalBundleKb}
|
|
382
|
+
{!isCollapsed && (<react_native_1.View style={bundleStyles.treeChildrenContainer}>
|
|
383
|
+
{node.children.map((child, cIdx) => (<BundleTreeNodeView key={child.id} node={child} level={level + 1} search={search} totalBundleKb={totalBundleKb} expandedFolders={expandedFolders} toggleFolder={toggleFolder} isLastChild={cIdx === node.children.length - 1}/>))}
|
|
381
384
|
</react_native_1.View>)}
|
|
382
385
|
</react_native_1.View>);
|
|
383
386
|
}
|
|
@@ -385,64 +388,41 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, collapsedFolde
|
|
|
385
388
|
const file = node.fileItem;
|
|
386
389
|
if (!file)
|
|
387
390
|
return null;
|
|
388
|
-
const pctOfTotal = ((file.sizeKb / totalBundleKb) * 100).toFixed(1);
|
|
391
|
+
const pctOfTotal = totalBundleKb > 0 ? ((file.sizeKb / totalBundleKb) * 100).toFixed(1) : '0';
|
|
389
392
|
const isUnused = file.isConsumed === false;
|
|
390
|
-
return (<react_native_1.View style={[
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
393
|
+
return (<react_native_1.View style={[
|
|
394
|
+
bundleStyles.treeFileRow,
|
|
395
|
+
{ paddingLeft: indentLeft },
|
|
396
|
+
isUnused && bundleStyles.treeFileRowUnused,
|
|
397
|
+
]}>
|
|
398
|
+
<react_native_1.View style={bundleStyles.treeRowLeft}>
|
|
399
|
+
<react_native_1.View style={bundleStyles.treeBranchGuide}>
|
|
400
|
+
<react_native_1.Text style={bundleStyles.treeBranchGuideText}>
|
|
401
|
+
{isLastChild ? '└' : '├'}
|
|
395
402
|
</react_native_1.Text>
|
|
396
403
|
</react_native_1.View>
|
|
397
404
|
|
|
398
405
|
<MediaPreviewThumbnail file={file}/>
|
|
399
406
|
|
|
400
|
-
<
|
|
401
|
-
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
|
|
402
|
-
<HighlightText_1.default text={file.name} search={search} style={bundleStyles.fileName} highlightStyle={bundleStyles.searchHighlight}/>
|
|
403
|
-
{isUnused ? (<react_native_1.View style={bundleStyles.unusedBadge}>
|
|
404
|
-
<react_native_1.Text style={bundleStyles.unusedBadgeText}>{(0, i18n_1.t)('bundle.notConsumed')}</react_native_1.Text>
|
|
405
|
-
</react_native_1.View>) : (<react_native_1.View style={bundleStyles.consumedBadge}>
|
|
406
|
-
<react_native_1.Text style={bundleStyles.consumedBadgeText}>{(0, i18n_1.t)('bundle.consumed')}</react_native_1.Text>
|
|
407
|
-
</react_native_1.View>)}
|
|
408
|
-
</react_native_1.View>
|
|
409
|
-
<react_native_1.Text style={bundleStyles.filePath} numberOfLines={1}>
|
|
410
|
-
{file.meta}
|
|
411
|
-
</react_native_1.Text>
|
|
412
|
-
</react_native_1.View>
|
|
407
|
+
<HighlightText_1.default text={file.name} search={search} style={bundleStyles.treeFileName} highlightStyle={bundleStyles.searchHighlight}/>
|
|
413
408
|
|
|
414
|
-
<react_native_1.View style={
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
409
|
+
{isUnused && (<react_native_1.View style={bundleStyles.treeUnusedPill}>
|
|
410
|
+
<react_native_1.Text style={bundleStyles.treeUnusedPillText}>{(0, i18n_1.t)('bundle.notConsumed')}</react_native_1.Text>
|
|
411
|
+
</react_native_1.View>)}
|
|
412
|
+
</react_native_1.View>
|
|
413
|
+
|
|
414
|
+
<react_native_1.View style={bundleStyles.treeRowRight}>
|
|
415
|
+
<react_native_1.View style={bundleStyles.treeFileSizeGroup}>
|
|
416
|
+
<react_native_1.Text style={[bundleStyles.treeFileSizeText, isUnused && { color: AppColors_1.AppColors.red600 }]}>
|
|
417
|
+
{file.sizeKb >= 1024
|
|
418
418
|
? (0, i18n_1.t)('bundle.fileSizeMb', { size: (file.sizeKb / 1024).toFixed(2) })
|
|
419
419
|
: (0, i18n_1.t)('bundle.fileSizeKb', { size: file.sizeKb })}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
</react_native_1.View>
|
|
423
|
-
<CopyButton_1.default value={() => file} label={(0, i18n_1.t)('bundle.fileDetailsJson')}/>
|
|
420
|
+
</react_native_1.Text>
|
|
421
|
+
<react_native_1.Text style={bundleStyles.treeFilePctText}>{pctOfTotal}%</react_native_1.Text>
|
|
424
422
|
</react_native_1.View>
|
|
425
|
-
</react_native_1.View>
|
|
426
423
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
file.status === 'warning' && bundleStyles.adviceWarning,
|
|
430
|
-
file.status === 'optimal' && bundleStyles.adviceOptimal,
|
|
431
|
-
isUnused && bundleStyles.adviceUnused,
|
|
432
|
-
{ marginLeft: 26, marginTop: 4 },
|
|
433
|
-
]}>
|
|
434
|
-
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'flex-start', gap: 5 }}>
|
|
435
|
-
{isUnused ? (<NetworkIcons_1.TrashIcon color={AppColors_1.AppColors.red600} size={12}/>) : file.status === 'warning' ? (<NetworkIcons_1.LightbulbIcon color={AppColors_1.AppColors.amber800Warm} size={12}/>) : (<NetworkIcons_1.SparkleIcon color={AppColors_1.AppColors.emerald700} size={12}/>)}
|
|
436
|
-
<react_native_1.Text style={[
|
|
437
|
-
bundleStyles.adviceText,
|
|
438
|
-
file.status === 'warning' && { color: AppColors_1.AppColors.amber800Warm },
|
|
439
|
-
file.status === 'optimal' && { color: AppColors_1.AppColors.emerald700 },
|
|
440
|
-
isUnused && { color: AppColors_1.AppColors.red600 },
|
|
441
|
-
]}>
|
|
442
|
-
{file.advice}
|
|
443
|
-
</react_native_1.Text>
|
|
444
|
-
</react_native_1.View>
|
|
445
|
-
</react_native_1.View>)}
|
|
424
|
+
<CopyButton_1.default value={() => file} label={(0, i18n_1.t)('bundle.fileDetailsJson')}/>
|
|
425
|
+
</react_native_1.View>
|
|
446
426
|
</react_native_1.View>);
|
|
447
427
|
};
|
|
448
428
|
const CATEGORY_TABS = [
|
|
@@ -465,11 +445,19 @@ const CATEGORY_COLORS = {
|
|
|
465
445
|
const BundleTab = react_1.default.memo(() => {
|
|
466
446
|
const { t } = (0, i18n_1.useTranslation)();
|
|
467
447
|
const [activeSubTab, setActiveSubTab] = (0, react_1.useState)('overview');
|
|
448
|
+
const [prodPlatform, setProdPlatform] = (0, react_1.useState)('ios');
|
|
468
449
|
const [search, setSearch] = (0, react_1.useState)('');
|
|
469
450
|
const [activeCategory, setActiveCategory] = (0, react_1.useState)('ALL');
|
|
470
451
|
// ─── Live Host App Bundle Analysis (fetched from Metro / runtime) ─────────
|
|
471
452
|
const [analysis, setAnalysis] = (0, react_1.useState)(() => (0, bundleAnalyzer_1.getCachedBundleAnalysis)());
|
|
472
453
|
const [isAnalyzing, setIsAnalyzing] = (0, react_1.useState)(!(0, bundleAnalyzer_1.getCachedBundleAnalysis)());
|
|
454
|
+
const refreshAnalysis = (0, react_1.useCallback)(() => {
|
|
455
|
+
setIsAnalyzing(true);
|
|
456
|
+
(0, bundleAnalyzer_1.analyzeHostAppBundle)(true).then(result => {
|
|
457
|
+
setAnalysis(result);
|
|
458
|
+
setIsAnalyzing(false);
|
|
459
|
+
});
|
|
460
|
+
}, []);
|
|
473
461
|
(0, react_1.useEffect)(() => {
|
|
474
462
|
let mounted = true;
|
|
475
463
|
(0, bundleAnalyzer_1.analyzeHostAppBundle)().then(result => {
|
|
@@ -487,72 +475,108 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
487
475
|
// Dynamic files & packages derived from the analyzed host bundle
|
|
488
476
|
const bundleFiles = (0, react_1.useMemo)(() => (analysis ? analysis.files : []), [analysis]);
|
|
489
477
|
const bundlePackages = (0, react_1.useMemo)(() => (analysis ? analysis.packages : []), [analysis]);
|
|
490
|
-
//
|
|
478
|
+
// Comprehensive bundle summary (full Metro bundle calculation e.g. 6.0 MB)
|
|
491
479
|
const summary = (0, react_1.useMemo)(() => {
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
480
|
+
const totalKb = analysis?.totalDevKb || (analysis?.totalDevBytes ? Math.round(analysis.totalDevBytes / 1024) : 6144);
|
|
481
|
+
const totalMb = analysis?.totalDevMb ? analysis.totalDevMb.toFixed(2) : (totalKb / 1024).toFixed(2);
|
|
482
|
+
const nodeModulesKb = analysis?.splitUp?.nodeModules?.kb || Math.round(totalKb * 0.52);
|
|
483
|
+
const nodeModulesPct = analysis?.splitUp?.nodeModules?.pct || 52.0;
|
|
484
|
+
const metroKb = analysis?.splitUp?.metroDevOverhead?.kb || Math.round(totalKb * 0.21);
|
|
485
|
+
const metroPct = analysis?.splitUp?.metroDevOverhead?.pct || 21.0;
|
|
486
|
+
const appSourceKb = analysis?.splitUp?.appSource?.kb || Math.round(totalKb * 0.15);
|
|
487
|
+
const appSourcePct = analysis?.splitUp?.appSource?.pct || 15.0;
|
|
488
|
+
const assetsMediaKb = analysis?.splitUp?.assetsMedia?.kb || Math.round(totalKb * 0.12);
|
|
489
|
+
const assetsMediaPct = analysis?.splitUp?.assetsMedia?.pct || 12.0;
|
|
490
|
+
const categories = [
|
|
491
|
+
{
|
|
492
|
+
key: 'node_modules',
|
|
493
|
+
iconType: 'javascript',
|
|
494
|
+
title: 'NPM Dependencies',
|
|
495
|
+
targetTab: 'packages',
|
|
496
|
+
count: analysis?.packageCount || bundlePackages.length || 53,
|
|
497
|
+
sizeKb: nodeModulesKb,
|
|
498
|
+
sizeMb: (nodeModulesKb / 1024).toFixed(2),
|
|
499
|
+
pct: nodeModulesPct,
|
|
500
|
+
color: AppColors_1.AppColors.indigo500,
|
|
501
|
+
desc: `${analysis?.packageCount || bundlePackages.length || 53} node_modules packages (React Native, React, navigation, axios)`,
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
key: 'metro_runtime',
|
|
505
|
+
iconType: 'bolt',
|
|
506
|
+
title: 'Metro Dev Runtime',
|
|
507
|
+
targetTab: 'optimizer',
|
|
508
|
+
count: 1,
|
|
509
|
+
sizeKb: metroKb,
|
|
510
|
+
sizeMb: (metroKb / 1024).toFixed(2),
|
|
511
|
+
pct: metroPct,
|
|
512
|
+
color: AppColors_1.AppColors.amber500,
|
|
513
|
+
desc: 'Module loader, polyfills, HMR client, and prelude runtime',
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
key: 'app_source',
|
|
517
|
+
iconType: 'typescript',
|
|
518
|
+
title: 'App Source Code (TSX/JS)',
|
|
519
|
+
targetTab: 'files',
|
|
520
|
+
count: bundleFiles.filter(f => f.category === 'typescript' || f.category === 'javascript').length || 7,
|
|
521
|
+
sizeKb: appSourceKb,
|
|
522
|
+
sizeMb: (appSourceKb / 1024).toFixed(2),
|
|
523
|
+
pct: appSourcePct,
|
|
524
|
+
color: AppColors_1.AppColors.sky500,
|
|
525
|
+
desc: 'Screens, components, navigation, Redux store, and hooks',
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
key: 'assets_media',
|
|
529
|
+
iconType: 'image',
|
|
530
|
+
title: 'Images & Static Media',
|
|
531
|
+
targetTab: 'media',
|
|
532
|
+
count: bundleFiles.filter(f => f.category === 'image' || f.category === 'font' || f.category === 'json').length || 3,
|
|
533
|
+
sizeKb: assetsMediaKb,
|
|
534
|
+
sizeMb: (assetsMediaKb / 1024).toFixed(2),
|
|
535
|
+
pct: assetsMediaPct,
|
|
536
|
+
color: AppColors_1.AppColors.pink500,
|
|
537
|
+
desc: 'Bundled PNG/JPG/SVG drawables, custom fonts, and JSON assets',
|
|
538
|
+
},
|
|
539
|
+
];
|
|
525
540
|
return {
|
|
526
541
|
totalKb,
|
|
527
|
-
totalMb
|
|
528
|
-
totalCount: bundleFiles.length,
|
|
542
|
+
totalMb,
|
|
543
|
+
totalCount: (analysis?.packageCount || 53) + bundleFiles.length + 1,
|
|
544
|
+
categories,
|
|
545
|
+
nodeModulesKb,
|
|
546
|
+
nodeModulesPct,
|
|
547
|
+
metroKb,
|
|
548
|
+
metroPct,
|
|
549
|
+
appSourceKb,
|
|
550
|
+
appSourcePct,
|
|
551
|
+
assetsMediaKb,
|
|
552
|
+
assetsMediaPct,
|
|
529
553
|
images: {
|
|
530
|
-
count:
|
|
531
|
-
kb:
|
|
532
|
-
pct:
|
|
554
|
+
count: bundleFiles.filter(f => f.category === 'image').length,
|
|
555
|
+
kb: assetsMediaKb,
|
|
556
|
+
pct: assetsMediaPct,
|
|
533
557
|
},
|
|
534
558
|
ts: {
|
|
535
|
-
count:
|
|
536
|
-
kb:
|
|
537
|
-
pct:
|
|
559
|
+
count: bundleFiles.filter(f => f.category === 'typescript').length,
|
|
560
|
+
kb: appSourceKb,
|
|
561
|
+
pct: appSourcePct,
|
|
538
562
|
},
|
|
539
563
|
js: {
|
|
540
|
-
count:
|
|
541
|
-
kb:
|
|
542
|
-
pct:
|
|
564
|
+
count: (analysis?.packageCount || 53) + 1,
|
|
565
|
+
kb: nodeModulesKb + metroKb,
|
|
566
|
+
pct: Number((nodeModulesPct + metroPct).toFixed(1)),
|
|
543
567
|
},
|
|
544
568
|
fonts: {
|
|
545
|
-
count:
|
|
546
|
-
kb:
|
|
547
|
-
pct:
|
|
569
|
+
count: bundleFiles.filter(f => f.category === 'font').length,
|
|
570
|
+
kb: 0,
|
|
571
|
+
pct: 0,
|
|
548
572
|
},
|
|
549
573
|
json: {
|
|
550
|
-
count:
|
|
551
|
-
kb:
|
|
552
|
-
pct:
|
|
574
|
+
count: bundleFiles.filter(f => f.category === 'json').length,
|
|
575
|
+
kb: Math.round(assetsMediaKb * 0.1),
|
|
576
|
+
pct: Number((assetsMediaPct * 0.1).toFixed(1)),
|
|
553
577
|
},
|
|
554
578
|
};
|
|
555
|
-
}, [bundleFiles]);
|
|
579
|
+
}, [analysis, bundleFiles, bundlePackages]);
|
|
556
580
|
// Filtered files
|
|
557
581
|
const filteredFiles = (0, react_1.useMemo)(() => {
|
|
558
582
|
return bundleFiles.filter(file => {
|
|
@@ -574,22 +598,19 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
574
598
|
const filteredTotalKb = (0, react_1.useMemo)(() => {
|
|
575
599
|
return filteredFiles.reduce((acc, f) => acc + f.sizeKb, 0);
|
|
576
600
|
}, [filteredFiles]);
|
|
577
|
-
// Tree View State & Node Generation
|
|
601
|
+
// Tree View State & Node Generation (Collapsed by default)
|
|
578
602
|
const [filesViewMode, setFilesViewMode] = (0, react_1.useState)('tree');
|
|
579
|
-
const [
|
|
603
|
+
const [expandedFolders, setExpandedFolders] = (0, react_1.useState)({});
|
|
580
604
|
const fileTreeNodes = (0, react_1.useMemo)(() => {
|
|
581
605
|
return buildBundleFileTree(filteredFiles);
|
|
582
606
|
}, [filteredFiles]);
|
|
583
607
|
const toggleFolder = (0, react_1.useCallback)((path) => {
|
|
584
|
-
|
|
608
|
+
setExpandedFolders(prev => ({
|
|
585
609
|
...prev,
|
|
586
610
|
[path]: !prev[path],
|
|
587
611
|
}));
|
|
588
612
|
}, []);
|
|
589
613
|
const expandAllFolders = (0, react_1.useCallback)(() => {
|
|
590
|
-
setCollapsedFolders({});
|
|
591
|
-
}, []);
|
|
592
|
-
const collapseAllFolders = (0, react_1.useCallback)(() => {
|
|
593
614
|
const all = {};
|
|
594
615
|
function collect(nodes) {
|
|
595
616
|
for (const n of nodes) {
|
|
@@ -600,8 +621,11 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
600
621
|
}
|
|
601
622
|
}
|
|
602
623
|
collect(fileTreeNodes);
|
|
603
|
-
|
|
624
|
+
setExpandedFolders(all);
|
|
604
625
|
}, [fileTreeNodes]);
|
|
626
|
+
const collapseAllFolders = (0, react_1.useCallback)(() => {
|
|
627
|
+
setExpandedFolders({});
|
|
628
|
+
}, []);
|
|
605
629
|
// Filtered Packages
|
|
606
630
|
const filteredPackages = (0, react_1.useMemo)(() => {
|
|
607
631
|
if (!search)
|
|
@@ -627,6 +651,11 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
627
651
|
label: t('bundle.tabOverview'),
|
|
628
652
|
icon: (isActive) => (<NetworkIcons_1.LiveStateIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={12}/>),
|
|
629
653
|
},
|
|
654
|
+
{
|
|
655
|
+
key: 'production',
|
|
656
|
+
label: t('bundle.tabProduction', { count: 3 }),
|
|
657
|
+
icon: (isActive) => (<NetworkIcons_1.TimelineIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={12}/>),
|
|
658
|
+
},
|
|
630
659
|
{
|
|
631
660
|
key: 'files',
|
|
632
661
|
label: t('bundle.tabFiles', { count: bundleFiles.length }),
|
|
@@ -649,9 +678,9 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
649
678
|
},
|
|
650
679
|
];
|
|
651
680
|
return (<react_native_1.View style={{ flex: 1, backgroundColor: AppColors_1.AppColors.grayBackground }}>
|
|
652
|
-
{/* ─── Top Sub-Tabs Navigation Bar (Scrollable Pill Bar) ─── */}
|
|
681
|
+
{/* ─── Top Sub-Tabs Navigation Bar (Scrollable Pill Bar + Dynamic Refresh) ─── */}
|
|
653
682
|
<react_native_1.View style={bundleStyles.topTabWrap}>
|
|
654
|
-
<react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={bundleStyles.subTabsScroll}>
|
|
683
|
+
<react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} style={{ flex: 1 }} contentContainerStyle={bundleStyles.subTabsScroll}>
|
|
655
684
|
{subTabs.map(tab => {
|
|
656
685
|
const isActive = activeSubTab === tab.key;
|
|
657
686
|
return (<TouchableScale_1.default key={tab.key} onPress={() => setActiveSubTab(tab.key)} style={[
|
|
@@ -668,6 +697,9 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
668
697
|
</TouchableScale_1.default>);
|
|
669
698
|
})}
|
|
670
699
|
</react_native_1.ScrollView>
|
|
700
|
+
<TouchableScale_1.default onPress={refreshAnalysis} style={bundleStyles.reloadButton} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}>
|
|
701
|
+
{isAnalyzing ? (<react_native_1.ActivityIndicator size="small" color={AppColors_1.AppColors.brandPurple}/>) : (<NetworkIcons_1.RefreshCcwIcon color={AppColors_1.AppColors.brandPurple} size={14}/>)}
|
|
702
|
+
</TouchableScale_1.default>
|
|
671
703
|
</react_native_1.View>
|
|
672
704
|
|
|
673
705
|
{/* ─── Live Bundle Analysis Loading State ─── */}
|
|
@@ -694,11 +726,57 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
694
726
|
</react_native_1.View>
|
|
695
727
|
<react_native_1.View style={{ flex: 1 }}>
|
|
696
728
|
<react_native_1.Text style={bundleStyles.heroTitle}>{t('bundle.heroTitle')}</react_native_1.Text>
|
|
697
|
-
<react_native_1.
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
729
|
+
{analysis?.isLive && analysis.scriptURL ? (<react_native_1.View style={{ marginTop: 4, gap: 4 }}>
|
|
730
|
+
<react_native_1.Text style={bundleStyles.heroSubtitle}>
|
|
731
|
+
{t('bundle.heroSubtitle')}
|
|
732
|
+
</react_native_1.Text>
|
|
733
|
+
<react_native_1.Pressable style={{
|
|
734
|
+
backgroundColor: `${AppColors_1.AppColors.skyBlue}10`,
|
|
735
|
+
borderColor: `${AppColors_1.AppColors.skyBlue}30`,
|
|
736
|
+
borderWidth: 1,
|
|
737
|
+
borderRadius: 8,
|
|
738
|
+
padding: 8,
|
|
739
|
+
marginTop: 2,
|
|
740
|
+
}} onPress={() => react_native_1.Linking.openURL(analysis.scriptURL)}>
|
|
741
|
+
<react_native_1.View style={{
|
|
742
|
+
flexDirection: 'row',
|
|
743
|
+
alignItems: 'center',
|
|
744
|
+
justifyContent: 'space-between',
|
|
745
|
+
marginBottom: 3,
|
|
746
|
+
}}>
|
|
747
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
|
|
748
|
+
<NetworkIcons_1.ExternalLinkIcon color={AppColors_1.AppColors.skyBlue} size={11}/>
|
|
749
|
+
<react_native_1.Text style={{
|
|
750
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
751
|
+
fontSize: 9.5,
|
|
752
|
+
color: AppColors_1.AppColors.skyBlue,
|
|
753
|
+
letterSpacing: 0.3,
|
|
754
|
+
textTransform: 'uppercase',
|
|
755
|
+
}}>
|
|
756
|
+
Live Metro URL ↗
|
|
757
|
+
</react_native_1.Text>
|
|
758
|
+
</react_native_1.View>
|
|
759
|
+
<react_native_1.Text style={{
|
|
760
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
761
|
+
fontSize: 9.5,
|
|
762
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
763
|
+
}}>
|
|
764
|
+
{analysis.scriptURL.length} chars
|
|
765
|
+
</react_native_1.Text>
|
|
766
|
+
</react_native_1.View>
|
|
767
|
+
<react_native_1.Text selectable={true} style={{
|
|
768
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
769
|
+
fontSize: 11,
|
|
770
|
+
color: AppColors_1.AppColors.skyBlue,
|
|
771
|
+
textDecorationLine: 'underline',
|
|
772
|
+
lineHeight: 16,
|
|
773
|
+
}}>
|
|
774
|
+
{analysis.scriptURL}
|
|
775
|
+
</react_native_1.Text>
|
|
776
|
+
</react_native_1.Pressable>
|
|
777
|
+
</react_native_1.View>) : (<react_native_1.Text style={bundleStyles.heroSubtitle}>
|
|
778
|
+
{t('bundle.heroSubtitle')}
|
|
779
|
+
</react_native_1.Text>)}
|
|
702
780
|
</react_native_1.View>
|
|
703
781
|
<CopyButton_1.default value={() => ({ ...summary, bundle: analysis })} label={t('bundle.bundleOverviewJson')}/>
|
|
704
782
|
</react_native_1.View>
|
|
@@ -777,93 +855,7 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
777
855
|
</react_native_1.View>
|
|
778
856
|
</react_native_1.View>)}
|
|
779
857
|
|
|
780
|
-
{/* Development Bundle Split-Up (derived from the real running bundle) */}
|
|
781
|
-
{analysis && (<react_native_1.View style={bundleStyles.sectionCard}>
|
|
782
|
-
<react_native_1.View style={bundleStyles.sectionHeaderRow}>
|
|
783
|
-
<react_native_1.View>
|
|
784
|
-
<react_native_1.Text style={bundleStyles.sectionTitle}>{t('bundle.splitUpTitle')}</react_native_1.Text>
|
|
785
|
-
<react_native_1.Text style={bundleStyles.sectionSub}>
|
|
786
|
-
{t('bundle.splitUpSub', {
|
|
787
|
-
mb: analysis.totalDevMb,
|
|
788
|
-
files: analysis.filesCount,
|
|
789
|
-
packages: analysis.packageCount,
|
|
790
|
-
})}
|
|
791
|
-
</react_native_1.Text>
|
|
792
|
-
</react_native_1.View>
|
|
793
|
-
<CopyButton_1.default value={() => analysis.splitUp} label={t('bundle.splitUpJson')}/>
|
|
794
|
-
</react_native_1.View>
|
|
795
858
|
|
|
796
|
-
{[
|
|
797
|
-
{
|
|
798
|
-
iconType: 'source',
|
|
799
|
-
label: t('bundle.splitAppSource'),
|
|
800
|
-
color: AppColors_1.AppColors.sky500,
|
|
801
|
-
...analysis.splitUp.appSource,
|
|
802
|
-
},
|
|
803
|
-
{
|
|
804
|
-
iconType: 'deps',
|
|
805
|
-
label: t('bundle.splitNodeModules'),
|
|
806
|
-
color: AppColors_1.AppColors.indigo500,
|
|
807
|
-
...analysis.splitUp.nodeModules,
|
|
808
|
-
},
|
|
809
|
-
{
|
|
810
|
-
iconType: 'media',
|
|
811
|
-
label: t('bundle.splitAssetsMedia'),
|
|
812
|
-
color: AppColors_1.AppColors.pink500,
|
|
813
|
-
...analysis.splitUp.assetsMedia,
|
|
814
|
-
},
|
|
815
|
-
{
|
|
816
|
-
iconType: 'overhead',
|
|
817
|
-
label: t('bundle.splitMetroOverhead'),
|
|
818
|
-
color: AppColors_1.AppColors.amber500,
|
|
819
|
-
...analysis.splitUp.metroDevOverhead,
|
|
820
|
-
},
|
|
821
|
-
].map((part, idx) => (<react_native_1.View key={idx} style={bundleStyles.catRowCard}>
|
|
822
|
-
<react_native_1.View style={bundleStyles.catRowTop}>
|
|
823
|
-
<BundleCategoryIcon type={part.iconType} size={18} color={part.color}/>
|
|
824
|
-
<react_native_1.View style={{ flex: 1 }}>
|
|
825
|
-
<react_native_1.Text style={bundleStyles.catRowTitle}>{part.label}</react_native_1.Text>
|
|
826
|
-
<react_native_1.Text style={bundleStyles.catRowDesc}>
|
|
827
|
-
{t('bundle.splitSize', { kb: part.kb, mb: part.mb })}
|
|
828
|
-
</react_native_1.Text>
|
|
829
|
-
</react_native_1.View>
|
|
830
|
-
<react_native_1.View style={{ alignItems: 'flex-end' }}>
|
|
831
|
-
<react_native_1.Text style={bundleStyles.catRowSize}>{part.pct}%</react_native_1.Text>
|
|
832
|
-
</react_native_1.View>
|
|
833
|
-
</react_native_1.View>
|
|
834
|
-
<react_native_1.View style={bundleStyles.catProgressTrack}>
|
|
835
|
-
<react_native_1.View style={[
|
|
836
|
-
bundleStyles.catProgressBar,
|
|
837
|
-
{ width: `${part.pct}%`, backgroundColor: part.color },
|
|
838
|
-
]}/>
|
|
839
|
-
</react_native_1.View>
|
|
840
|
-
</react_native_1.View>))}
|
|
841
|
-
|
|
842
|
-
{/* Production Binary Footprint */}
|
|
843
|
-
<react_native_1.View style={bundleStyles.totalSummaryCard}>
|
|
844
|
-
<react_native_1.View style={bundleStyles.totalSummaryRow}>
|
|
845
|
-
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
846
|
-
<NetworkIcons_1.PackageIcon color={AppColors_1.AppColors.purple} size={16}/>
|
|
847
|
-
<react_native_1.Text style={bundleStyles.totalSummaryLabel}>
|
|
848
|
-
{t('bundle.productionFootprint')}
|
|
849
|
-
</react_native_1.Text>
|
|
850
|
-
</react_native_1.View>
|
|
851
|
-
<react_native_1.Text style={bundleStyles.totalSummaryValue}>
|
|
852
|
-
{t('bundle.productionValue', {
|
|
853
|
-
ios: analysis.production.ios.totalInstallMb,
|
|
854
|
-
android: analysis.production.android.totalInstallMb,
|
|
855
|
-
})}
|
|
856
|
-
</react_native_1.Text>
|
|
857
|
-
</react_native_1.View>
|
|
858
|
-
<react_native_1.Text style={bundleStyles.totalSummaryFormula}>
|
|
859
|
-
{t('bundle.productionDownload', {
|
|
860
|
-
ios: analysis.production.ios.totalDownloadMb,
|
|
861
|
-
aab: analysis.production.androidAab.totalDownloadMb,
|
|
862
|
-
apk: analysis.production.androidApk.totalDownloadMb,
|
|
863
|
-
})}
|
|
864
|
-
</react_native_1.Text>
|
|
865
|
-
</react_native_1.View>
|
|
866
|
-
</react_native_1.View>)}
|
|
867
859
|
|
|
868
860
|
{/* Visual Type Distribution Ratio Bar */}
|
|
869
861
|
<react_native_1.View style={bundleStyles.sectionCard}>
|
|
@@ -877,67 +869,64 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
877
869
|
<CopyButton_1.default value={() => ({
|
|
878
870
|
totalMb: summary.totalMb,
|
|
879
871
|
totalKb: summary.totalKb,
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
json: summary.json,
|
|
872
|
+
nodeModules: { kb: summary.nodeModulesKb, pct: summary.nodeModulesPct },
|
|
873
|
+
metroRuntime: { kb: summary.metroKb, pct: summary.metroPct },
|
|
874
|
+
appSource: { kb: summary.appSourceKb, pct: summary.appSourcePct },
|
|
875
|
+
assetsMedia: { kb: summary.assetsMediaKb, pct: summary.assetsMediaPct },
|
|
885
876
|
})} label={t('bundle.treemapJson')}/>
|
|
886
877
|
</react_native_1.View>
|
|
887
878
|
|
|
888
|
-
{/* Stacked Colored Bar */}
|
|
879
|
+
{/* Stacked Colored Bar for Full 6.0 MB Bundle */}
|
|
889
880
|
<react_native_1.View style={bundleStyles.treemapBar}>
|
|
890
|
-
<react_native_1.View style={{ flex: summary.
|
|
891
|
-
<react_native_1.View style={{ flex: summary.
|
|
892
|
-
<react_native_1.View style={{ flex: summary.
|
|
893
|
-
<react_native_1.View style={{ flex: summary.
|
|
894
|
-
<react_native_1.View style={{ flex: summary.json.pct, backgroundColor: AppColors_1.AppColors.emerald500, height: 16 }}/>
|
|
881
|
+
<react_native_1.View style={{ flex: summary.nodeModulesPct, backgroundColor: AppColors_1.AppColors.indigo500, height: 16 }}/>
|
|
882
|
+
<react_native_1.View style={{ flex: summary.metroPct, backgroundColor: AppColors_1.AppColors.amber500, height: 16 }}/>
|
|
883
|
+
<react_native_1.View style={{ flex: summary.appSourcePct, backgroundColor: AppColors_1.AppColors.sky500, height: 16 }}/>
|
|
884
|
+
<react_native_1.View style={{ flex: summary.assetsMediaPct, backgroundColor: AppColors_1.AppColors.pink500, height: 16 }}/>
|
|
895
885
|
</react_native_1.View>
|
|
896
886
|
|
|
897
887
|
{/* Legend Grid */}
|
|
898
888
|
<react_native_1.View style={bundleStyles.legendGrid}>
|
|
899
889
|
<react_native_1.View style={bundleStyles.legendItem}>
|
|
900
|
-
<BundleCategoryIcon type="
|
|
901
|
-
<react_native_1.Text style={bundleStyles.legendText}>
|
|
902
|
-
{t('bundle.legendImages')}{' '}
|
|
903
|
-
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
904
|
-
{t('bundle.legendValue', { kb: summary.images.kb, pct: summary.images.pct })}
|
|
905
|
-
</react_native_1.Text>
|
|
906
|
-
</react_native_1.Text>
|
|
907
|
-
</react_native_1.View>
|
|
908
|
-
<react_native_1.View style={bundleStyles.legendItem}>
|
|
909
|
-
<BundleCategoryIcon type="typescript" size={13} color={AppColors_1.AppColors.sky500}/>
|
|
890
|
+
<BundleCategoryIcon type="javascript" size={13} color={AppColors_1.AppColors.indigo500}/>
|
|
910
891
|
<react_native_1.Text style={bundleStyles.legendText}>
|
|
911
|
-
{
|
|
892
|
+
Node Modules{' '}
|
|
912
893
|
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
913
|
-
{
|
|
894
|
+
{summary.nodeModulesKb >= 1024
|
|
895
|
+
? `${(summary.nodeModulesKb / 1024).toFixed(1)} MB`
|
|
896
|
+
: `${summary.nodeModulesKb} KB`} ({summary.nodeModulesPct}%)
|
|
914
897
|
</react_native_1.Text>
|
|
915
898
|
</react_native_1.Text>
|
|
916
899
|
</react_native_1.View>
|
|
917
900
|
<react_native_1.View style={bundleStyles.legendItem}>
|
|
918
|
-
<BundleCategoryIcon type="
|
|
901
|
+
<BundleCategoryIcon type="overhead" size={13} color={AppColors_1.AppColors.amber500}/>
|
|
919
902
|
<react_native_1.Text style={bundleStyles.legendText}>
|
|
920
|
-
{
|
|
903
|
+
Metro Runtime{' '}
|
|
921
904
|
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
922
|
-
{
|
|
905
|
+
{summary.metroKb >= 1024
|
|
906
|
+
? `${(summary.metroKb / 1024).toFixed(1)} MB`
|
|
907
|
+
: `${summary.metroKb} KB`} ({summary.metroPct}%)
|
|
923
908
|
</react_native_1.Text>
|
|
924
909
|
</react_native_1.Text>
|
|
925
910
|
</react_native_1.View>
|
|
926
911
|
<react_native_1.View style={bundleStyles.legendItem}>
|
|
927
|
-
<BundleCategoryIcon type="
|
|
912
|
+
<BundleCategoryIcon type="typescript" size={13} color={AppColors_1.AppColors.sky500}/>
|
|
928
913
|
<react_native_1.Text style={bundleStyles.legendText}>
|
|
929
|
-
{
|
|
914
|
+
App Source{' '}
|
|
930
915
|
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
931
|
-
{
|
|
916
|
+
{summary.appSourceKb >= 1024
|
|
917
|
+
? `${(summary.appSourceKb / 1024).toFixed(1)} MB`
|
|
918
|
+
: `${summary.appSourceKb} KB`} ({summary.appSourcePct}%)
|
|
932
919
|
</react_native_1.Text>
|
|
933
920
|
</react_native_1.Text>
|
|
934
921
|
</react_native_1.View>
|
|
935
922
|
<react_native_1.View style={bundleStyles.legendItem}>
|
|
936
|
-
<BundleCategoryIcon type="
|
|
923
|
+
<BundleCategoryIcon type="image" size={13} color={AppColors_1.AppColors.pink500}/>
|
|
937
924
|
<react_native_1.Text style={bundleStyles.legendText}>
|
|
938
|
-
{
|
|
925
|
+
Assets & Media{' '}
|
|
939
926
|
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
940
|
-
{
|
|
927
|
+
{summary.assetsMediaKb >= 1024
|
|
928
|
+
? `${(summary.assetsMediaKb / 1024).toFixed(1)} MB`
|
|
929
|
+
: `${summary.assetsMediaKb} KB`} ({summary.assetsMediaPct}%)
|
|
941
930
|
</react_native_1.Text>
|
|
942
931
|
</react_native_1.Text>
|
|
943
932
|
</react_native_1.View>
|
|
@@ -948,118 +937,333 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
948
937
|
<react_native_1.View style={bundleStyles.sectionCard}>
|
|
949
938
|
<react_native_1.View style={bundleStyles.sectionHeaderRow}>
|
|
950
939
|
<react_native_1.Text style={bundleStyles.sectionTitle}>{t('bundle.categoryBreakdown')}</react_native_1.Text>
|
|
951
|
-
<CopyButton_1.default value={() => (
|
|
952
|
-
totalAssets: summary.totalCount,
|
|
953
|
-
totalSizeKb: summary.totalKb,
|
|
954
|
-
categories: {
|
|
955
|
-
images: summary.images,
|
|
956
|
-
javascript: summary.js,
|
|
957
|
-
fonts: summary.fonts,
|
|
958
|
-
typescript: summary.ts,
|
|
959
|
-
json: summary.json,
|
|
960
|
-
},
|
|
961
|
-
})} label={t('bundle.categoriesJson')}/>
|
|
940
|
+
<CopyButton_1.default value={() => summary} label={t('bundle.categoriesJson')}/>
|
|
962
941
|
</react_native_1.View>
|
|
963
942
|
|
|
964
|
-
{[
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
count: summary.images.count,
|
|
969
|
-
size: t('bundle.fileSizeKb', { size: summary.images.kb }),
|
|
970
|
-
pct: summary.images.pct,
|
|
971
|
-
color: AppColors_1.AppColors.pink500,
|
|
972
|
-
desc: t('bundle.catImagesDesc'),
|
|
973
|
-
},
|
|
974
|
-
{
|
|
975
|
-
iconType: 'javascript',
|
|
976
|
-
title: t('bundle.catJsTitle'),
|
|
977
|
-
count: summary.js.count,
|
|
978
|
-
size: t('bundle.fileSizeKb', { size: summary.js.kb }),
|
|
979
|
-
pct: summary.js.pct,
|
|
980
|
-
color: AppColors_1.AppColors.indigo500,
|
|
981
|
-
desc: t('bundle.catJsDesc'),
|
|
982
|
-
},
|
|
983
|
-
{
|
|
984
|
-
iconType: 'font',
|
|
985
|
-
title: t('bundle.catFontsTitle'),
|
|
986
|
-
count: summary.fonts.count,
|
|
987
|
-
size: t('bundle.fileSizeKb', { size: summary.fonts.kb }),
|
|
988
|
-
pct: summary.fonts.pct,
|
|
989
|
-
color: AppColors_1.AppColors.purple500,
|
|
990
|
-
desc: bundleFiles
|
|
991
|
-
.filter(f => f.category === 'font')
|
|
992
|
-
.map(f => f.name)
|
|
993
|
-
.join(', ') || t('bundle.catFontsDesc'),
|
|
994
|
-
},
|
|
995
|
-
{
|
|
996
|
-
iconType: 'typescript',
|
|
997
|
-
title: t('bundle.catTsTitle'),
|
|
998
|
-
count: summary.ts.count,
|
|
999
|
-
size: t('bundle.fileSizeKb', { size: summary.ts.kb }),
|
|
1000
|
-
pct: summary.ts.pct,
|
|
1001
|
-
color: AppColors_1.AppColors.sky500,
|
|
1002
|
-
desc: t('bundle.catTsDesc'),
|
|
1003
|
-
},
|
|
1004
|
-
{
|
|
1005
|
-
iconType: 'json',
|
|
1006
|
-
title: t('bundle.catJsonTitle'),
|
|
1007
|
-
count: summary.json.count,
|
|
1008
|
-
size: t('bundle.fileSizeKb', { size: summary.json.kb }),
|
|
1009
|
-
pct: summary.json.pct,
|
|
1010
|
-
color: AppColors_1.AppColors.emerald500,
|
|
1011
|
-
desc: t('bundle.catJsonDesc'),
|
|
1012
|
-
},
|
|
1013
|
-
].map((cat, cIdx) => (<react_native_1.View key={cIdx} style={bundleStyles.catRowCard}>
|
|
943
|
+
{summary.categories.map((cat, cIdx) => (<react_native_1.Pressable key={cIdx} style={({ pressed }) => [
|
|
944
|
+
bundleStyles.catRowCard,
|
|
945
|
+
pressed && { opacity: 0.85, transform: [{ scale: 0.99 }] },
|
|
946
|
+
]} onPress={() => setActiveSubTab(cat.targetTab)}>
|
|
1014
947
|
<react_native_1.View style={bundleStyles.catRowTop}>
|
|
1015
|
-
<
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
</react_native_1.Text>
|
|
948
|
+
<react_native_1.View style={[
|
|
949
|
+
bundleStyles.catIconBox,
|
|
950
|
+
{ backgroundColor: `${cat.color}15`, borderColor: `${cat.color}30` },
|
|
951
|
+
]}>
|
|
952
|
+
<BundleCategoryIcon type={cat.iconType} size={18} color={cat.color}/>
|
|
1021
953
|
</react_native_1.View>
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
<react_native_1.
|
|
954
|
+
|
|
955
|
+
<react_native_1.View style={bundleStyles.catRowTitleWrap}>
|
|
956
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: 6 }}>
|
|
957
|
+
<react_native_1.Text style={bundleStyles.catRowTitle} numberOfLines={1}>
|
|
958
|
+
{cat.title}
|
|
959
|
+
</react_native_1.Text>
|
|
960
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
961
|
+
<react_native_1.Text style={bundleStyles.catRowSize}>
|
|
962
|
+
{cat.sizeKb >= 1024 ? `${cat.sizeMb} MB` : `${cat.sizeKb} KB`}
|
|
963
|
+
</react_native_1.Text>
|
|
964
|
+
<react_native_1.View style={[
|
|
965
|
+
bundleStyles.catPctPill,
|
|
966
|
+
{ backgroundColor: `${cat.color}18` },
|
|
967
|
+
]}>
|
|
968
|
+
<react_native_1.Text style={[bundleStyles.catPctText, { color: cat.color }]}>
|
|
969
|
+
{cat.pct}%
|
|
970
|
+
</react_native_1.Text>
|
|
971
|
+
</react_native_1.View>
|
|
972
|
+
</react_native_1.View>
|
|
973
|
+
</react_native_1.View>
|
|
974
|
+
|
|
975
|
+
<react_native_1.Text style={bundleStyles.catRowDesc} numberOfLines={2}>
|
|
976
|
+
{cat.count} items • {cat.desc}
|
|
977
|
+
</react_native_1.Text>
|
|
1025
978
|
</react_native_1.View>
|
|
1026
979
|
</react_native_1.View>
|
|
980
|
+
|
|
981
|
+
{/* Modern Rounded Progress Bar */}
|
|
1027
982
|
<react_native_1.View style={bundleStyles.catProgressTrack}>
|
|
1028
983
|
<react_native_1.View style={[
|
|
1029
984
|
bundleStyles.catProgressBar,
|
|
1030
985
|
{ width: `${cat.pct}%`, backgroundColor: cat.color },
|
|
1031
986
|
]}/>
|
|
1032
987
|
</react_native_1.View>
|
|
1033
|
-
</react_native_1.
|
|
988
|
+
</react_native_1.Pressable>))}
|
|
1034
989
|
|
|
1035
|
-
{/* Total Summation Card */}
|
|
990
|
+
{/* Executive Total Summation Card */}
|
|
1036
991
|
<react_native_1.View style={bundleStyles.totalSummaryCard}>
|
|
1037
992
|
<react_native_1.View style={bundleStyles.totalSummaryRow}>
|
|
1038
|
-
<react_native_1.View style={
|
|
1039
|
-
<
|
|
1040
|
-
|
|
1041
|
-
|
|
993
|
+
<react_native_1.View style={bundleStyles.totalSummaryLabelWrap}>
|
|
994
|
+
<react_native_1.View style={bundleStyles.totalIconBadge}>
|
|
995
|
+
<NetworkIcons_1.PackageIcon color={AppColors_1.AppColors.brandPurple} size={16}/>
|
|
996
|
+
</react_native_1.View>
|
|
997
|
+
<react_native_1.View>
|
|
998
|
+
<react_native_1.Text style={bundleStyles.totalSummaryLabel}>
|
|
999
|
+
TOTAL BUNDLE ASSETS
|
|
1000
|
+
</react_native_1.Text>
|
|
1001
|
+
<react_native_1.Text style={bundleStyles.totalSummarySub}>
|
|
1002
|
+
{summary.totalCount} Tracked Modules & Media Assets
|
|
1003
|
+
</react_native_1.Text>
|
|
1004
|
+
</react_native_1.View>
|
|
1005
|
+
</react_native_1.View>
|
|
1006
|
+
<react_native_1.View style={{ alignItems: 'flex-end' }}>
|
|
1007
|
+
<react_native_1.Text style={bundleStyles.totalSummaryValue}>
|
|
1008
|
+
{summary.totalMb} MB
|
|
1009
|
+
</react_native_1.Text>
|
|
1010
|
+
<react_native_1.Text style={bundleStyles.totalSummaryKb}>
|
|
1011
|
+
{summary.totalKb.toLocaleString()} KB
|
|
1042
1012
|
</react_native_1.Text>
|
|
1043
1013
|
</react_native_1.View>
|
|
1044
|
-
<react_native_1.Text style={bundleStyles.totalSummaryValue}>
|
|
1045
|
-
{t('bundle.totalBundleValue', { kb: summary.totalKb, mb: summary.totalMb })}
|
|
1046
|
-
</react_native_1.Text>
|
|
1047
1014
|
</react_native_1.View>
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1015
|
+
|
|
1016
|
+
{/* 4-Pill Chip Breakdown */}
|
|
1017
|
+
<react_native_1.View style={bundleStyles.totalFormulaGrid}>
|
|
1018
|
+
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1019
|
+
<react_native_1.View style={[bundleStyles.totalDot, { backgroundColor: AppColors_1.AppColors.indigo500 }]}/>
|
|
1020
|
+
<react_native_1.Text style={bundleStyles.totalChipText}>NPM: {(summary.nodeModulesKb / 1024).toFixed(1)}M ({summary.nodeModulesPct}%)</react_native_1.Text>
|
|
1021
|
+
</react_native_1.View>
|
|
1022
|
+
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1023
|
+
<react_native_1.View style={[bundleStyles.totalDot, { backgroundColor: AppColors_1.AppColors.amber500 }]}/>
|
|
1024
|
+
<react_native_1.Text style={bundleStyles.totalChipText}>Metro: {(summary.metroKb / 1024).toFixed(1)}M ({summary.metroPct}%)</react_native_1.Text>
|
|
1025
|
+
</react_native_1.View>
|
|
1026
|
+
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1027
|
+
<react_native_1.View style={[bundleStyles.totalDot, { backgroundColor: AppColors_1.AppColors.sky500 }]}/>
|
|
1028
|
+
<react_native_1.Text style={bundleStyles.totalChipText}>Source: {(summary.appSourceKb / 1024).toFixed(1)}M ({summary.appSourcePct}%)</react_native_1.Text>
|
|
1029
|
+
</react_native_1.View>
|
|
1030
|
+
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1031
|
+
<react_native_1.View style={[bundleStyles.totalDot, { backgroundColor: AppColors_1.AppColors.pink500 }]}/>
|
|
1032
|
+
<react_native_1.Text style={bundleStyles.totalChipText}>Media: {summary.assetsMediaKb}K ({summary.assetsMediaPct}%)</react_native_1.Text>
|
|
1033
|
+
</react_native_1.View>
|
|
1034
|
+
</react_native_1.View>
|
|
1059
1035
|
</react_native_1.View>
|
|
1060
1036
|
</react_native_1.View>
|
|
1061
1037
|
</react_native_1.ScrollView>)}
|
|
1062
1038
|
|
|
1039
|
+
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1040
|
+
{/* ── 2. TAB: PRODUCTION BUILDS & PLATFORMS ───────────────────────────── */}
|
|
1041
|
+
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1042
|
+
{activeSubTab === 'production' && !isAnalyzing && (<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
|
|
1043
|
+
|
|
1044
|
+
{/* Platform Segmented Switcher (Horizontally Scrollable) */}
|
|
1045
|
+
<react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={bundleStyles.prodPlatformScroll}>
|
|
1046
|
+
{[
|
|
1047
|
+
{ key: 'ios', label: 'iOS App (.ipa)', badge: `${analysis?.production.ios.totalInstallMb || 59.2} MB` },
|
|
1048
|
+
{ key: 'androidAab', label: 'Android AAB (.aab)', badge: `${analysis?.production.androidAab.totalInstallMb || 24.3} MB` },
|
|
1049
|
+
{ key: 'androidApk', label: 'Universal APK (.apk)', badge: `${analysis?.production.androidApk.totalInstallMb || 64.0} MB` },
|
|
1050
|
+
].map(tab => {
|
|
1051
|
+
const isSelected = prodPlatform === tab.key;
|
|
1052
|
+
return (<TouchableScale_1.default key={tab.key} onPress={() => setProdPlatform(tab.key)} style={[
|
|
1053
|
+
bundleStyles.prodPlatformBtn,
|
|
1054
|
+
isSelected && bundleStyles.prodPlatformBtnActive,
|
|
1055
|
+
]}>
|
|
1056
|
+
<react_native_1.Text style={[
|
|
1057
|
+
bundleStyles.prodPlatformBtnText,
|
|
1058
|
+
isSelected && bundleStyles.prodPlatformBtnTextActive,
|
|
1059
|
+
]}>
|
|
1060
|
+
{tab.label}
|
|
1061
|
+
</react_native_1.Text>
|
|
1062
|
+
<react_native_1.View style={[
|
|
1063
|
+
bundleStyles.prodPlatformBadge,
|
|
1064
|
+
isSelected && bundleStyles.prodPlatformBadgeActive,
|
|
1065
|
+
]}>
|
|
1066
|
+
<react_native_1.Text style={[
|
|
1067
|
+
bundleStyles.prodPlatformBadgeText,
|
|
1068
|
+
isSelected && bundleStyles.prodPlatformBadgeTextActive,
|
|
1069
|
+
]}>
|
|
1070
|
+
{tab.badge}
|
|
1071
|
+
</react_native_1.Text>
|
|
1072
|
+
</react_native_1.View>
|
|
1073
|
+
</TouchableScale_1.default>);
|
|
1074
|
+
})}
|
|
1075
|
+
</react_native_1.ScrollView>
|
|
1076
|
+
|
|
1077
|
+
{/* Production Platform Metrics Hero */}
|
|
1078
|
+
{analysis && (<react_native_1.View style={bundleStyles.heroCard}>
|
|
1079
|
+
<react_native_1.View style={bundleStyles.heroTopRow}>
|
|
1080
|
+
<react_native_1.View style={bundleStyles.heroIconWrap}>
|
|
1081
|
+
<NetworkIcons_1.PackageIcon color={AppColors_1.AppColors.brandPurple} size={24}/>
|
|
1082
|
+
</react_native_1.View>
|
|
1083
|
+
<react_native_1.View style={{ flex: 1 }}>
|
|
1084
|
+
<react_native_1.Text style={bundleStyles.heroTitle}>
|
|
1085
|
+
{prodPlatform === 'ios'
|
|
1086
|
+
? 'iOS Production Binary Footprint'
|
|
1087
|
+
: prodPlatform === 'androidAab'
|
|
1088
|
+
? 'Google Play App Bundle (.aab)'
|
|
1089
|
+
: 'Universal Standalone APK (.apk)'}
|
|
1090
|
+
</react_native_1.Text>
|
|
1091
|
+
<react_native_1.Text style={bundleStyles.heroSubtitle}>
|
|
1092
|
+
{prodPlatform === 'ios'
|
|
1093
|
+
? 'App Store install & over-the-air cellular download estimates'
|
|
1094
|
+
: prodPlatform === 'androidAab'
|
|
1095
|
+
? 'Optimized per-device dynamic delivery split APK architecture'
|
|
1096
|
+
: 'Multi-ABI universal install archive for sideloading & direct distribution'}
|
|
1097
|
+
</react_native_1.Text>
|
|
1098
|
+
</react_native_1.View>
|
|
1099
|
+
<CopyButton_1.default value={() => analysis.production[prodPlatform]} label="Production Binary JSON"/>
|
|
1100
|
+
</react_native_1.View>
|
|
1101
|
+
|
|
1102
|
+
{/* 4-Stat Balanced 2x2 Metric Grid */}
|
|
1103
|
+
<react_native_1.View style={bundleStyles.metricsGrid}>
|
|
1104
|
+
<react_native_1.View style={bundleStyles.metricBox}>
|
|
1105
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>INSTALL SIZE</react_native_1.Text>
|
|
1106
|
+
<react_native_1.Text style={[bundleStyles.metricValue, { color: AppColors_1.AppColors.purple }]}>
|
|
1107
|
+
{analysis.production[prodPlatform].totalInstallMb} MB
|
|
1108
|
+
</react_native_1.Text>
|
|
1109
|
+
<react_native_1.Text style={bundleStyles.metricHint}>On-device uncompressed footprint</react_native_1.Text>
|
|
1110
|
+
</react_native_1.View>
|
|
1111
|
+
|
|
1112
|
+
<react_native_1.View style={bundleStyles.metricBox}>
|
|
1113
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>DOWNLOAD SIZE</react_native_1.Text>
|
|
1114
|
+
<react_native_1.Text style={[bundleStyles.metricValue, { color: AppColors_1.AppColors.emerald600 }]}>
|
|
1115
|
+
~{analysis.production[prodPlatform].totalDownloadMb} MB
|
|
1116
|
+
</react_native_1.Text>
|
|
1117
|
+
<react_native_1.Text style={bundleStyles.metricHint}>Store network transfer payload</react_native_1.Text>
|
|
1118
|
+
</react_native_1.View>
|
|
1119
|
+
|
|
1120
|
+
<react_native_1.View style={bundleStyles.metricBox}>
|
|
1121
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>COMPRESSION</react_native_1.Text>
|
|
1122
|
+
<react_native_1.Text style={[bundleStyles.metricValue, { color: AppColors_1.AppColors.sky500 }]}>
|
|
1123
|
+
{analysis.production[prodPlatform].compressionRatioPct}%
|
|
1124
|
+
</react_native_1.Text>
|
|
1125
|
+
<react_native_1.Text style={bundleStyles.metricHint}>Bytecode & asset ratio</react_native_1.Text>
|
|
1126
|
+
</react_native_1.View>
|
|
1127
|
+
|
|
1128
|
+
<react_native_1.View style={bundleStyles.metricBox}>
|
|
1129
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>FORMAT ARCHITECTURE</react_native_1.Text>
|
|
1130
|
+
<react_native_1.Text style={[bundleStyles.metricValue, { color: AppColors_1.AppColors.amber700 }]}>
|
|
1131
|
+
{prodPlatform === 'ios'
|
|
1132
|
+
? 'Mach-O 64-bit'
|
|
1133
|
+
: prodPlatform === 'androidAab'
|
|
1134
|
+
? 'Split APKs'
|
|
1135
|
+
: 'FAT Multi-ABI'}
|
|
1136
|
+
</react_native_1.Text>
|
|
1137
|
+
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
1138
|
+
{prodPlatform === 'ios'
|
|
1139
|
+
? 'Apple ARM64 runtime'
|
|
1140
|
+
: prodPlatform === 'androidAab'
|
|
1141
|
+
? 'Dynamic Google Play delivery'
|
|
1142
|
+
: 'Sideload universal package'}
|
|
1143
|
+
</react_native_1.Text>
|
|
1144
|
+
</react_native_1.View>
|
|
1145
|
+
</react_native_1.View>
|
|
1146
|
+
</react_native_1.View>)}
|
|
1147
|
+
|
|
1148
|
+
{/* Component Breakdown Cards */}
|
|
1149
|
+
{analysis && (<react_native_1.View style={bundleStyles.sectionCard}>
|
|
1150
|
+
<react_native_1.View style={bundleStyles.sectionHeaderRow}>
|
|
1151
|
+
<react_native_1.View>
|
|
1152
|
+
<react_native_1.Text style={bundleStyles.sectionTitle}>Binary Component Architecture</react_native_1.Text>
|
|
1153
|
+
<react_native_1.Text style={bundleStyles.sectionSub}>
|
|
1154
|
+
Compiled native libraries, runtime bytecodes, assets, and signature blocks
|
|
1155
|
+
</react_native_1.Text>
|
|
1156
|
+
</react_native_1.View>
|
|
1157
|
+
<CopyButton_1.default value={() => analysis.production[prodPlatform].components} label="Components JSON"/>
|
|
1158
|
+
</react_native_1.View>
|
|
1159
|
+
|
|
1160
|
+
{analysis.production[prodPlatform].components.map((comp, idx) => (<react_native_1.View key={idx} style={bundleStyles.catRowCard}>
|
|
1161
|
+
<react_native_1.View style={bundleStyles.catRowTop}>
|
|
1162
|
+
<react_native_1.View style={[
|
|
1163
|
+
bundleStyles.catIconBox,
|
|
1164
|
+
{ backgroundColor: `${comp.color}15`, borderColor: `${comp.color}30` },
|
|
1165
|
+
]}>
|
|
1166
|
+
<BundleCategoryIcon type={comp.category === 'native'
|
|
1167
|
+
? 'source'
|
|
1168
|
+
: comp.category === 'frameworks'
|
|
1169
|
+
? 'deps'
|
|
1170
|
+
: comp.category === 'assets'
|
|
1171
|
+
? 'media'
|
|
1172
|
+
: comp.category === 'js'
|
|
1173
|
+
? 'javascript'
|
|
1174
|
+
: 'overhead'} size={18} color={comp.color}/>
|
|
1175
|
+
</react_native_1.View>
|
|
1176
|
+
|
|
1177
|
+
<react_native_1.View style={bundleStyles.catRowTitleWrap}>
|
|
1178
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: 6 }}>
|
|
1179
|
+
<react_native_1.Text style={bundleStyles.catRowTitle} numberOfLines={1}>
|
|
1180
|
+
{comp.name}
|
|
1181
|
+
</react_native_1.Text>
|
|
1182
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1183
|
+
<react_native_1.Text style={bundleStyles.catRowSize}>{comp.sizeMb} MB</react_native_1.Text>
|
|
1184
|
+
<react_native_1.View style={[
|
|
1185
|
+
bundleStyles.catPctPill,
|
|
1186
|
+
{ backgroundColor: `${comp.color}18` },
|
|
1187
|
+
]}>
|
|
1188
|
+
<react_native_1.Text style={[bundleStyles.catPctText, { color: comp.color }]}>
|
|
1189
|
+
{comp.pct}%
|
|
1190
|
+
</react_native_1.Text>
|
|
1191
|
+
</react_native_1.View>
|
|
1192
|
+
</react_native_1.View>
|
|
1193
|
+
</react_native_1.View>
|
|
1194
|
+
|
|
1195
|
+
<react_native_1.Text style={bundleStyles.catRowDesc} numberOfLines={2}>
|
|
1196
|
+
{comp.description}
|
|
1197
|
+
</react_native_1.Text>
|
|
1198
|
+
</react_native_1.View>
|
|
1199
|
+
</react_native_1.View>
|
|
1200
|
+
|
|
1201
|
+
<react_native_1.View style={bundleStyles.catProgressTrack}>
|
|
1202
|
+
<react_native_1.View style={[
|
|
1203
|
+
bundleStyles.catProgressBar,
|
|
1204
|
+
{ width: `${comp.pct}%`, backgroundColor: comp.color },
|
|
1205
|
+
]}/>
|
|
1206
|
+
</react_native_1.View>
|
|
1207
|
+
|
|
1208
|
+
{comp.advice ? (<react_native_1.View style={[bundleStyles.adviceBadge, bundleStyles.adviceOptimal, { marginTop: 6 }]}>
|
|
1209
|
+
<NetworkIcons_1.LightbulbIcon color={AppColors_1.AppColors.emerald700} size={13}/>
|
|
1210
|
+
<react_native_1.Text style={[bundleStyles.adviceText, { color: AppColors_1.AppColors.emerald700, flex: 1, marginLeft: 4 }]}>
|
|
1211
|
+
{comp.advice}
|
|
1212
|
+
</react_native_1.Text>
|
|
1213
|
+
</react_native_1.View>) : null}
|
|
1214
|
+
</react_native_1.View>))}
|
|
1215
|
+
|
|
1216
|
+
{/* Total Platform Binary Summary with JS Source Bundle Comparison */}
|
|
1217
|
+
<react_native_1.View style={bundleStyles.totalSummaryCard}>
|
|
1218
|
+
<react_native_1.View style={bundleStyles.totalSummaryRow}>
|
|
1219
|
+
<react_native_1.View style={bundleStyles.totalSummaryLabelWrap}>
|
|
1220
|
+
<react_native_1.View style={bundleStyles.totalIconBadge}>
|
|
1221
|
+
<NetworkIcons_1.PackageIcon color={AppColors_1.AppColors.brandPurple} size={16}/>
|
|
1222
|
+
</react_native_1.View>
|
|
1223
|
+
<react_native_1.View>
|
|
1224
|
+
<react_native_1.Text style={bundleStyles.totalSummaryLabel}>
|
|
1225
|
+
{prodPlatform === 'ios'
|
|
1226
|
+
? 'TOTAL IOS APP BINARY'
|
|
1227
|
+
: prodPlatform === 'androidAab'
|
|
1228
|
+
? 'TOTAL ANDROID AAB BUNDLE'
|
|
1229
|
+
: 'TOTAL UNIVERSAL APK'}
|
|
1230
|
+
</react_native_1.Text>
|
|
1231
|
+
<react_native_1.Text style={bundleStyles.totalSummarySub}>
|
|
1232
|
+
{prodPlatform === 'ios'
|
|
1233
|
+
? 'App Store install & cellular download estimates'
|
|
1234
|
+
: prodPlatform === 'androidAab'
|
|
1235
|
+
? 'Google Play dynamic delivery split APK'
|
|
1236
|
+
: 'Universal standalone sideload package'}
|
|
1237
|
+
</react_native_1.Text>
|
|
1238
|
+
</react_native_1.View>
|
|
1239
|
+
</react_native_1.View>
|
|
1240
|
+
</react_native_1.View>
|
|
1241
|
+
|
|
1242
|
+
{/* Platform Metric Grid Chips */}
|
|
1243
|
+
<react_native_1.View style={bundleStyles.totalFormulaGrid}>
|
|
1244
|
+
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1245
|
+
<react_native_1.View style={[bundleStyles.totalDot, { backgroundColor: AppColors_1.AppColors.purple }]}/>
|
|
1246
|
+
<react_native_1.Text style={bundleStyles.totalChipText}>
|
|
1247
|
+
Install: {analysis.production[prodPlatform].totalInstallMb} MB
|
|
1248
|
+
</react_native_1.Text>
|
|
1249
|
+
</react_native_1.View>
|
|
1250
|
+
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1251
|
+
<react_native_1.View style={[bundleStyles.totalDot, { backgroundColor: AppColors_1.AppColors.sky500 }]}/>
|
|
1252
|
+
<react_native_1.Text style={bundleStyles.totalChipText}>
|
|
1253
|
+
Download: ~{analysis.production[prodPlatform].totalDownloadMb} MB
|
|
1254
|
+
</react_native_1.Text>
|
|
1255
|
+
</react_native_1.View>
|
|
1256
|
+
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1257
|
+
<react_native_1.View style={[bundleStyles.totalDot, { backgroundColor: AppColors_1.AppColors.emerald500 }]}/>
|
|
1258
|
+
<react_native_1.Text style={bundleStyles.totalChipText}>
|
|
1259
|
+
Compression: {analysis.production[prodPlatform].compressionRatioPct}%
|
|
1260
|
+
</react_native_1.Text>
|
|
1261
|
+
</react_native_1.View>
|
|
1262
|
+
</react_native_1.View>
|
|
1263
|
+
</react_native_1.View>
|
|
1264
|
+
</react_native_1.View>)}
|
|
1265
|
+
</react_native_1.ScrollView>)}
|
|
1266
|
+
|
|
1063
1267
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1064
1268
|
{/* ── 2. TAB: FILES BREAKDOWN ─────────────────────────────────────────── */}
|
|
1065
1269
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
@@ -1151,8 +1355,8 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1151
1355
|
</react_native_1.View>
|
|
1152
1356
|
|
|
1153
1357
|
{/* ── MODE 1: DIRECTORY TREE VIEW ── */}
|
|
1154
|
-
{filesViewMode === 'tree' ? (<react_native_1.View style={bundleStyles.
|
|
1155
|
-
{fileTreeNodes.map((node, nIdx) => (<BundleTreeNodeView key={node.id} node={node} level={0} search={search} totalBundleKb={summary.totalKb}
|
|
1358
|
+
{filesViewMode === 'tree' ? (<react_native_1.View style={bundleStyles.treeRootCard}>
|
|
1359
|
+
{fileTreeNodes.map((node, nIdx) => (<BundleTreeNodeView key={node.id} node={node} level={0} search={search} totalBundleKb={summary.totalKb} expandedFolders={expandedFolders} toggleFolder={toggleFolder} isLastChild={nIdx === fileTreeNodes.length - 1}/>))}
|
|
1156
1360
|
</react_native_1.View>) : (
|
|
1157
1361
|
/* ── MODE 2: FLAT LIST VIEW ── */
|
|
1158
1362
|
filteredFiles.map((file, index) => {
|
|
@@ -1558,16 +1762,16 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1558
1762
|
badgeColor: AppColors_1.AppColors.indigo500,
|
|
1559
1763
|
},
|
|
1560
1764
|
].map((tip, tIdx) => (<react_native_1.View key={tIdx} style={bundleStyles.tipItem}>
|
|
1561
|
-
<react_native_1.View style={
|
|
1562
|
-
<react_native_1.View style={
|
|
1765
|
+
<react_native_1.View style={bundleStyles.tipItemHeader}>
|
|
1766
|
+
<react_native_1.View style={bundleStyles.tipTitleWrap}>
|
|
1563
1767
|
<react_native_1.View style={bundleStyles.sNoBadge}>
|
|
1564
1768
|
<react_native_1.Text style={bundleStyles.sNoText}>#{tIdx + 1}</react_native_1.Text>
|
|
1565
1769
|
</react_native_1.View>
|
|
1566
1770
|
<BundleCategoryIcon type={tip.iconType} size={14} color={tip.iconColor}/>
|
|
1567
1771
|
<react_native_1.Text style={bundleStyles.tipTitle}>{tip.title}</react_native_1.Text>
|
|
1568
1772
|
</react_native_1.View>
|
|
1569
|
-
<react_native_1.View style={
|
|
1570
|
-
<react_native_1.View style={[bundleStyles.impactBadge, { backgroundColor: `${tip.badgeColor}
|
|
1773
|
+
<react_native_1.View style={bundleStyles.tipActionWrap}>
|
|
1774
|
+
<react_native_1.View style={[bundleStyles.impactBadge, { backgroundColor: `${tip.badgeColor}18`, borderColor: `${tip.badgeColor}40` }]}>
|
|
1571
1775
|
<react_native_1.Text style={[bundleStyles.impactBadgeText, { color: tip.badgeColor }]}>
|
|
1572
1776
|
{tip.badge}
|
|
1573
1777
|
</react_native_1.Text>
|
|
@@ -1587,6 +1791,19 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
1587
1791
|
paddingVertical: 8,
|
|
1588
1792
|
borderBottomWidth: 1,
|
|
1589
1793
|
borderBottomColor: AppColors_1.AppColors.dividerColor,
|
|
1794
|
+
flexDirection: 'row',
|
|
1795
|
+
alignItems: 'center',
|
|
1796
|
+
paddingRight: 10,
|
|
1797
|
+
},
|
|
1798
|
+
reloadButton: {
|
|
1799
|
+
padding: 8,
|
|
1800
|
+
borderRadius: 20,
|
|
1801
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
1802
|
+
borderWidth: 1,
|
|
1803
|
+
borderColor: AppColors_1.AppColors.dividerColor,
|
|
1804
|
+
alignItems: 'center',
|
|
1805
|
+
justifyContent: 'center',
|
|
1806
|
+
marginLeft: 4,
|
|
1590
1807
|
},
|
|
1591
1808
|
analyzingContainer: {
|
|
1592
1809
|
flex: 1,
|
|
@@ -1659,7 +1876,7 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
1659
1876
|
},
|
|
1660
1877
|
heroTopRow: {
|
|
1661
1878
|
flexDirection: 'row',
|
|
1662
|
-
alignItems: '
|
|
1879
|
+
alignItems: 'flex-start',
|
|
1663
1880
|
gap: 12,
|
|
1664
1881
|
marginBottom: 16,
|
|
1665
1882
|
},
|
|
@@ -1721,6 +1938,57 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
1721
1938
|
height: 8,
|
|
1722
1939
|
borderRadius: 4,
|
|
1723
1940
|
},
|
|
1941
|
+
prodPlatformScroll: {
|
|
1942
|
+
flexDirection: 'row',
|
|
1943
|
+
alignItems: 'center',
|
|
1944
|
+
gap: 8,
|
|
1945
|
+
paddingBottom: 4,
|
|
1946
|
+
},
|
|
1947
|
+
prodPlatformBtn: {
|
|
1948
|
+
flexDirection: 'row',
|
|
1949
|
+
alignItems: 'center',
|
|
1950
|
+
paddingVertical: 7,
|
|
1951
|
+
paddingHorizontal: 12,
|
|
1952
|
+
borderRadius: 20,
|
|
1953
|
+
backgroundColor: AppColors_1.AppColors.white,
|
|
1954
|
+
borderWidth: 1,
|
|
1955
|
+
borderColor: AppColors_1.AppColors.dividerColor,
|
|
1956
|
+
gap: 6,
|
|
1957
|
+
},
|
|
1958
|
+
prodPlatformBtnActive: {
|
|
1959
|
+
backgroundColor: AppColors_1.AppColors.brandPurple,
|
|
1960
|
+
borderColor: AppColors_1.AppColors.brandPurple,
|
|
1961
|
+
shadowColor: AppColors_1.AppColors.brandPurple,
|
|
1962
|
+
shadowOffset: { width: 0, height: 2 },
|
|
1963
|
+
shadowOpacity: 0.18,
|
|
1964
|
+
shadowRadius: 3,
|
|
1965
|
+
elevation: 2,
|
|
1966
|
+
},
|
|
1967
|
+
prodPlatformBtnText: {
|
|
1968
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1969
|
+
fontSize: 11.5,
|
|
1970
|
+
color: AppColors_1.AppColors.grayTextStrong,
|
|
1971
|
+
},
|
|
1972
|
+
prodPlatformBtnTextActive: {
|
|
1973
|
+
color: AppColors_1.AppColors.white,
|
|
1974
|
+
},
|
|
1975
|
+
prodPlatformBadge: {
|
|
1976
|
+
paddingHorizontal: 6,
|
|
1977
|
+
paddingVertical: 2,
|
|
1978
|
+
borderRadius: 10,
|
|
1979
|
+
backgroundColor: `${AppColors_1.AppColors.purple}14`,
|
|
1980
|
+
},
|
|
1981
|
+
prodPlatformBadgeActive: {
|
|
1982
|
+
backgroundColor: 'rgba(255, 255, 255, 0.25)',
|
|
1983
|
+
},
|
|
1984
|
+
prodPlatformBadgeText: {
|
|
1985
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1986
|
+
fontSize: 9.5,
|
|
1987
|
+
color: AppColors_1.AppColors.purple,
|
|
1988
|
+
},
|
|
1989
|
+
prodPlatformBadgeTextActive: {
|
|
1990
|
+
color: AppColors_1.AppColors.white,
|
|
1991
|
+
},
|
|
1724
1992
|
sectionCard: {
|
|
1725
1993
|
backgroundColor: AppColors_1.AppColors.white,
|
|
1726
1994
|
borderRadius: 14,
|
|
@@ -1755,18 +2023,21 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
1755
2023
|
legendGrid: {
|
|
1756
2024
|
flexDirection: 'row',
|
|
1757
2025
|
flexWrap: 'wrap',
|
|
1758
|
-
|
|
2026
|
+
justifyContent: 'space-between',
|
|
2027
|
+
rowGap: 8,
|
|
2028
|
+
columnGap: 10,
|
|
1759
2029
|
},
|
|
1760
2030
|
legendItem: {
|
|
1761
2031
|
flexDirection: 'row',
|
|
1762
2032
|
alignItems: 'center',
|
|
1763
|
-
gap:
|
|
1764
|
-
|
|
2033
|
+
gap: 6,
|
|
2034
|
+
width: '48%',
|
|
1765
2035
|
},
|
|
1766
2036
|
legendText: {
|
|
1767
2037
|
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
1768
2038
|
fontSize: 11,
|
|
1769
2039
|
color: AppColors_1.AppColors.grayTextStrong,
|
|
2040
|
+
flex: 1,
|
|
1770
2041
|
},
|
|
1771
2042
|
legendVal: {
|
|
1772
2043
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
@@ -1774,47 +2045,79 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
1774
2045
|
},
|
|
1775
2046
|
catRowCard: {
|
|
1776
2047
|
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
1777
|
-
borderRadius:
|
|
1778
|
-
padding:
|
|
2048
|
+
borderRadius: 12,
|
|
2049
|
+
padding: 12,
|
|
1779
2050
|
marginBottom: 8,
|
|
1780
2051
|
borderWidth: 1,
|
|
1781
2052
|
borderColor: AppColors_1.AppColors.dividerColor,
|
|
2053
|
+
gap: 8,
|
|
1782
2054
|
},
|
|
1783
2055
|
catRowTop: {
|
|
1784
2056
|
flexDirection: 'row',
|
|
2057
|
+
alignItems: 'flex-start',
|
|
2058
|
+
gap: 10,
|
|
2059
|
+
},
|
|
2060
|
+
catIconBox: {
|
|
2061
|
+
width: 36,
|
|
2062
|
+
height: 36,
|
|
2063
|
+
borderRadius: 10,
|
|
2064
|
+
borderWidth: 1,
|
|
1785
2065
|
alignItems: 'center',
|
|
1786
|
-
|
|
1787
|
-
|
|
2066
|
+
justifyContent: 'center',
|
|
2067
|
+
flexShrink: 0,
|
|
2068
|
+
},
|
|
2069
|
+
catRowTitleWrap: {
|
|
2070
|
+
flex: 1,
|
|
2071
|
+
minWidth: 0,
|
|
2072
|
+
gap: 2,
|
|
1788
2073
|
},
|
|
1789
2074
|
catRowTitle: {
|
|
1790
2075
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1791
|
-
fontSize:
|
|
2076
|
+
fontSize: 13,
|
|
1792
2077
|
color: AppColors_1.AppColors.primaryBlack,
|
|
2078
|
+
flex: 1,
|
|
1793
2079
|
},
|
|
1794
2080
|
catRowDesc: {
|
|
1795
2081
|
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
1796
|
-
fontSize: 10,
|
|
2082
|
+
fontSize: 10.5,
|
|
1797
2083
|
color: AppColors_1.AppColors.grayTextWeak,
|
|
2084
|
+
lineHeight: 14.5,
|
|
1798
2085
|
},
|
|
1799
2086
|
catRowSize: {
|
|
1800
2087
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1801
|
-
fontSize: 12,
|
|
2088
|
+
fontSize: 12.5,
|
|
1802
2089
|
color: AppColors_1.AppColors.primaryBlack,
|
|
1803
2090
|
},
|
|
2091
|
+
catRowRight: {
|
|
2092
|
+
alignItems: 'flex-end',
|
|
2093
|
+
justifyContent: 'center',
|
|
2094
|
+
flexShrink: 0,
|
|
2095
|
+
minWidth: 64,
|
|
2096
|
+
},
|
|
1804
2097
|
catRowPct: {
|
|
1805
2098
|
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
1806
2099
|
fontSize: 10,
|
|
1807
2100
|
color: AppColors_1.AppColors.grayTextWeak,
|
|
1808
2101
|
},
|
|
2102
|
+
catPctPill: {
|
|
2103
|
+
paddingHorizontal: 5.5,
|
|
2104
|
+
paddingVertical: 1.5,
|
|
2105
|
+
borderRadius: 5,
|
|
2106
|
+
},
|
|
2107
|
+
catPctText: {
|
|
2108
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2109
|
+
fontSize: 9.5,
|
|
2110
|
+
},
|
|
1809
2111
|
catProgressTrack: {
|
|
1810
|
-
height:
|
|
1811
|
-
borderRadius: 2,
|
|
2112
|
+
height: 5,
|
|
2113
|
+
borderRadius: 2.5,
|
|
1812
2114
|
backgroundColor: `${AppColors_1.AppColors.slate200}`,
|
|
1813
2115
|
overflow: 'hidden',
|
|
2116
|
+
marginTop: 2,
|
|
1814
2117
|
},
|
|
1815
2118
|
catProgressBar: {
|
|
1816
2119
|
height: '100%',
|
|
1817
|
-
borderRadius: 2,
|
|
2120
|
+
borderRadius: 2.5,
|
|
1818
2121
|
},
|
|
1819
2122
|
filterContainer: {
|
|
1820
2123
|
backgroundColor: AppColors_1.AppColors.white,
|
|
@@ -1918,32 +2221,44 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
1918
2221
|
fontSize: 11.5,
|
|
1919
2222
|
color: AppColors_1.AppColors.purple,
|
|
1920
2223
|
},
|
|
1921
|
-
|
|
1922
|
-
gap: 6,
|
|
1923
|
-
},
|
|
1924
|
-
treeFolderContainer: {
|
|
2224
|
+
treeRootCard: {
|
|
1925
2225
|
backgroundColor: AppColors_1.AppColors.white,
|
|
1926
|
-
borderRadius:
|
|
2226
|
+
borderRadius: 12,
|
|
1927
2227
|
borderWidth: 1,
|
|
1928
2228
|
borderColor: AppColors_1.AppColors.dividerColor,
|
|
1929
2229
|
overflow: 'hidden',
|
|
1930
|
-
marginBottom:
|
|
2230
|
+
marginBottom: 16,
|
|
2231
|
+
},
|
|
2232
|
+
treeFolderBlock: {
|
|
2233
|
+
borderBottomWidth: react_native_1.StyleSheet.hairlineWidth,
|
|
2234
|
+
borderBottomColor: AppColors_1.AppColors.dividerColor,
|
|
1931
2235
|
},
|
|
1932
|
-
|
|
2236
|
+
treeFolderRow: {
|
|
1933
2237
|
flexDirection: 'row',
|
|
1934
2238
|
alignItems: 'center',
|
|
1935
2239
|
justifyContent: 'space-between',
|
|
1936
|
-
paddingVertical:
|
|
2240
|
+
paddingVertical: 8,
|
|
1937
2241
|
paddingRight: 10,
|
|
1938
|
-
backgroundColor: `${AppColors_1.AppColors.purple}
|
|
1939
|
-
borderBottomWidth: 1,
|
|
1940
|
-
borderBottomColor: `${AppColors_1.AppColors.purple}14`,
|
|
2242
|
+
backgroundColor: `${AppColors_1.AppColors.purple}06`,
|
|
1941
2243
|
},
|
|
1942
|
-
|
|
1943
|
-
|
|
2244
|
+
treeRowLeft: {
|
|
2245
|
+
flexDirection: 'row',
|
|
2246
|
+
alignItems: 'center',
|
|
2247
|
+
gap: 6,
|
|
2248
|
+
flex: 1,
|
|
2249
|
+
marginRight: 6,
|
|
2250
|
+
},
|
|
2251
|
+
treeRowRight: {
|
|
2252
|
+
flexDirection: 'row',
|
|
2253
|
+
alignItems: 'center',
|
|
2254
|
+
gap: 6,
|
|
2255
|
+
},
|
|
2256
|
+
treeChevron: {
|
|
2257
|
+
fontSize: 12,
|
|
1944
2258
|
color: AppColors_1.AppColors.purple,
|
|
1945
2259
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1946
|
-
width:
|
|
2260
|
+
width: 12,
|
|
2261
|
+
textAlign: 'center',
|
|
1947
2262
|
},
|
|
1948
2263
|
treeFolderName: {
|
|
1949
2264
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
@@ -1951,44 +2266,75 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
1951
2266
|
color: AppColors_1.AppColors.primaryBlack,
|
|
1952
2267
|
},
|
|
1953
2268
|
treeCountBadge: {
|
|
1954
|
-
paddingHorizontal:
|
|
1955
|
-
paddingVertical: 1
|
|
1956
|
-
borderRadius:
|
|
1957
|
-
backgroundColor: `${AppColors_1.AppColors.purple}
|
|
2269
|
+
paddingHorizontal: 5,
|
|
2270
|
+
paddingVertical: 1,
|
|
2271
|
+
borderRadius: 8,
|
|
2272
|
+
backgroundColor: `${AppColors_1.AppColors.purple}14`,
|
|
1958
2273
|
},
|
|
1959
2274
|
treeCountBadgeText: {
|
|
1960
2275
|
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
1961
|
-
fontSize:
|
|
2276
|
+
fontSize: 9.5,
|
|
1962
2277
|
color: AppColors_1.AppColors.purple,
|
|
1963
2278
|
},
|
|
1964
2279
|
treeFolderSize: {
|
|
1965
|
-
fontFamily: AppFonts_1.AppFonts.
|
|
1966
|
-
fontSize: 11
|
|
1967
|
-
color: AppColors_1.AppColors.
|
|
2280
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
2281
|
+
fontSize: 11,
|
|
2282
|
+
color: AppColors_1.AppColors.grayTextStrong,
|
|
1968
2283
|
},
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
paddingVertical: 6,
|
|
1972
|
-
paddingRight: 8,
|
|
1973
|
-
gap: 4,
|
|
2284
|
+
treeChildrenContainer: {
|
|
2285
|
+
backgroundColor: AppColors_1.AppColors.white,
|
|
1974
2286
|
},
|
|
1975
|
-
|
|
2287
|
+
treeFileRow: {
|
|
2288
|
+
flexDirection: 'row',
|
|
2289
|
+
alignItems: 'center',
|
|
2290
|
+
justifyContent: 'space-between',
|
|
2291
|
+
paddingVertical: 6,
|
|
2292
|
+
paddingRight: 10,
|
|
2293
|
+
borderBottomWidth: react_native_1.StyleSheet.hairlineWidth,
|
|
2294
|
+
borderBottomColor: `${AppColors_1.AppColors.dividerColor}80`,
|
|
1976
2295
|
backgroundColor: AppColors_1.AppColors.white,
|
|
1977
|
-
borderRadius: 8,
|
|
1978
|
-
paddingVertical: 8,
|
|
1979
|
-
paddingHorizontal: 8,
|
|
1980
|
-
borderWidth: 1,
|
|
1981
|
-
borderColor: AppColors_1.AppColors.dividerColor,
|
|
1982
|
-
marginBottom: 4,
|
|
1983
2296
|
},
|
|
1984
|
-
|
|
1985
|
-
|
|
2297
|
+
treeFileRowUnused: {
|
|
2298
|
+
backgroundColor: `${AppColors_1.AppColors.red500}06`,
|
|
2299
|
+
},
|
|
2300
|
+
treeBranchGuide: {
|
|
2301
|
+
width: 12,
|
|
1986
2302
|
alignItems: 'center',
|
|
1987
2303
|
justifyContent: 'center',
|
|
1988
2304
|
},
|
|
1989
|
-
|
|
2305
|
+
treeBranchGuideText: {
|
|
1990
2306
|
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
1991
2307
|
fontSize: 11,
|
|
2308
|
+
color: AppColors_1.AppColors.dividerColor,
|
|
2309
|
+
},
|
|
2310
|
+
treeFileName: {
|
|
2311
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
2312
|
+
fontSize: 12,
|
|
2313
|
+
color: AppColors_1.AppColors.primaryBlack,
|
|
2314
|
+
flexShrink: 1,
|
|
2315
|
+
},
|
|
2316
|
+
treeUnusedPill: {
|
|
2317
|
+
paddingHorizontal: 5,
|
|
2318
|
+
paddingVertical: 1,
|
|
2319
|
+
borderRadius: 4,
|
|
2320
|
+
backgroundColor: `${AppColors_1.AppColors.red500}18`,
|
|
2321
|
+
},
|
|
2322
|
+
treeUnusedPillText: {
|
|
2323
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2324
|
+
fontSize: 9,
|
|
2325
|
+
color: AppColors_1.AppColors.red600,
|
|
2326
|
+
},
|
|
2327
|
+
treeFileSizeGroup: {
|
|
2328
|
+
alignItems: 'flex-end',
|
|
2329
|
+
},
|
|
2330
|
+
treeFileSizeText: {
|
|
2331
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
2332
|
+
fontSize: 11,
|
|
2333
|
+
color: AppColors_1.AppColors.primaryBlack,
|
|
2334
|
+
},
|
|
2335
|
+
treeFilePctText: {
|
|
2336
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
2337
|
+
fontSize: 9,
|
|
1992
2338
|
color: AppColors_1.AppColors.grayTextWeak,
|
|
1993
2339
|
},
|
|
1994
2340
|
fileCard: {
|
|
@@ -2320,27 +2666,80 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
2320
2666
|
},
|
|
2321
2667
|
totalSummaryCard: {
|
|
2322
2668
|
marginTop: 10,
|
|
2323
|
-
backgroundColor: `${AppColors_1.AppColors.
|
|
2324
|
-
borderRadius:
|
|
2669
|
+
backgroundColor: `${AppColors_1.AppColors.brandPurple}0B`,
|
|
2670
|
+
borderRadius: 12,
|
|
2325
2671
|
padding: 12,
|
|
2326
2672
|
borderWidth: 1,
|
|
2327
|
-
borderColor: `${AppColors_1.AppColors.
|
|
2328
|
-
gap:
|
|
2673
|
+
borderColor: `${AppColors_1.AppColors.brandPurple}25`,
|
|
2674
|
+
gap: 8,
|
|
2329
2675
|
},
|
|
2330
2676
|
totalSummaryRow: {
|
|
2331
2677
|
flexDirection: 'row',
|
|
2332
2678
|
justifyContent: 'space-between',
|
|
2333
2679
|
alignItems: 'center',
|
|
2334
2680
|
},
|
|
2681
|
+
totalSummaryLabelWrap: {
|
|
2682
|
+
flexDirection: 'row',
|
|
2683
|
+
alignItems: 'center',
|
|
2684
|
+
gap: 8,
|
|
2685
|
+
},
|
|
2686
|
+
totalIconBadge: {
|
|
2687
|
+
width: 32,
|
|
2688
|
+
height: 32,
|
|
2689
|
+
borderRadius: 8,
|
|
2690
|
+
backgroundColor: `${AppColors_1.AppColors.brandPurple}15`,
|
|
2691
|
+
alignItems: 'center',
|
|
2692
|
+
justifyContent: 'center',
|
|
2693
|
+
},
|
|
2335
2694
|
totalSummaryLabel: {
|
|
2336
2695
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2337
|
-
fontSize: 11,
|
|
2338
|
-
color: AppColors_1.AppColors.
|
|
2339
|
-
letterSpacing: 0.
|
|
2696
|
+
fontSize: 11.5,
|
|
2697
|
+
color: AppColors_1.AppColors.brandPurple,
|
|
2698
|
+
letterSpacing: 0.6,
|
|
2699
|
+
},
|
|
2700
|
+
totalSummarySub: {
|
|
2701
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
2702
|
+
fontSize: 10,
|
|
2703
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
2704
|
+
marginTop: 1,
|
|
2340
2705
|
},
|
|
2341
2706
|
totalSummaryValue: {
|
|
2342
2707
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2343
|
-
fontSize:
|
|
2708
|
+
fontSize: 15,
|
|
2709
|
+
color: AppColors_1.AppColors.primaryBlack,
|
|
2710
|
+
},
|
|
2711
|
+
totalSummaryKb: {
|
|
2712
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
2713
|
+
fontSize: 10,
|
|
2714
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
2715
|
+
},
|
|
2716
|
+
totalFormulaGrid: {
|
|
2717
|
+
flexDirection: 'row',
|
|
2718
|
+
flexWrap: 'wrap',
|
|
2719
|
+
gap: 6,
|
|
2720
|
+
paddingTop: 6,
|
|
2721
|
+
borderTopWidth: 1,
|
|
2722
|
+
borderTopColor: `${AppColors_1.AppColors.brandPurple}15`,
|
|
2723
|
+
},
|
|
2724
|
+
totalChip: {
|
|
2725
|
+
flexDirection: 'row',
|
|
2726
|
+
alignItems: 'center',
|
|
2727
|
+
gap: 4,
|
|
2728
|
+
backgroundColor: AppColors_1.AppColors.white,
|
|
2729
|
+
borderRadius: 6,
|
|
2730
|
+
paddingHorizontal: 6,
|
|
2731
|
+
paddingVertical: 3,
|
|
2732
|
+
borderWidth: 1,
|
|
2733
|
+
borderColor: AppColors_1.AppColors.dividerColor,
|
|
2734
|
+
},
|
|
2735
|
+
totalDot: {
|
|
2736
|
+
width: 6,
|
|
2737
|
+
height: 6,
|
|
2738
|
+
borderRadius: 3,
|
|
2739
|
+
},
|
|
2740
|
+
totalChipText: {
|
|
2741
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2742
|
+
fontSize: 9.5,
|
|
2344
2743
|
color: AppColors_1.AppColors.primaryBlack,
|
|
2345
2744
|
},
|
|
2346
2745
|
totalSummaryFormula: {
|
|
@@ -2375,24 +2774,45 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
2375
2774
|
color: AppColors_1.AppColors.purple,
|
|
2376
2775
|
},
|
|
2377
2776
|
tipItem: {
|
|
2378
|
-
marginBottom:
|
|
2777
|
+
marginBottom: 10,
|
|
2379
2778
|
backgroundColor: AppColors_1.AppColors.white,
|
|
2380
|
-
padding:
|
|
2381
|
-
borderRadius:
|
|
2779
|
+
padding: 12,
|
|
2780
|
+
borderRadius: 10,
|
|
2382
2781
|
borderWidth: 1,
|
|
2383
2782
|
borderColor: AppColors_1.AppColors.purple200,
|
|
2783
|
+
gap: 6,
|
|
2784
|
+
},
|
|
2785
|
+
tipItemHeader: {
|
|
2786
|
+
flexDirection: 'row',
|
|
2787
|
+
alignItems: 'flex-start',
|
|
2788
|
+
justifyContent: 'space-between',
|
|
2789
|
+
gap: 8,
|
|
2790
|
+
},
|
|
2791
|
+
tipTitleWrap: {
|
|
2792
|
+
flexDirection: 'row',
|
|
2793
|
+
alignItems: 'center',
|
|
2794
|
+
gap: 6,
|
|
2795
|
+
flex: 1,
|
|
2796
|
+
flexShrink: 1,
|
|
2797
|
+
},
|
|
2798
|
+
tipActionWrap: {
|
|
2799
|
+
flexDirection: 'row',
|
|
2800
|
+
alignItems: 'center',
|
|
2801
|
+
gap: 6,
|
|
2802
|
+
flexShrink: 0,
|
|
2384
2803
|
},
|
|
2385
2804
|
tipTitle: {
|
|
2386
2805
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2387
2806
|
fontSize: 12,
|
|
2388
2807
|
color: AppColors_1.AppColors.purple900,
|
|
2808
|
+
flex: 1,
|
|
2809
|
+
flexShrink: 1,
|
|
2389
2810
|
},
|
|
2390
2811
|
tipDesc: {
|
|
2391
2812
|
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
2392
2813
|
fontSize: 11,
|
|
2393
2814
|
color: AppColors_1.AppColors.gray500,
|
|
2394
2815
|
lineHeight: 16,
|
|
2395
|
-
marginTop: 4,
|
|
2396
2816
|
},
|
|
2397
2817
|
});
|
|
2398
2818
|
exports.default = BundleTab;
|