react-native-inapp-inspector 1.1.21 → 1.1.22
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/AnalyticsDetail.js +5 -3
- package/dist/commonjs/components/AnalyticsEventCard.d.ts +0 -1
- package/dist/commonjs/components/AnalyticsEventCard.js +85 -96
- package/dist/commonjs/components/Inspector/BundleTab.js +486 -651
- package/dist/commonjs/components/Inspector/PerformanceTab.js +185 -244
- package/dist/commonjs/components/Inspector/ReduxDetail.js +2 -2
- package/dist/commonjs/components/Inspector/ReduxTab.js +3 -3
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/bundleAnalyzer.d.ts +115 -0
- package/dist/commonjs/customHooks/bundleAnalyzer.js +561 -0
- package/dist/commonjs/customHooks/performanceTracker.d.ts +84 -0
- package/dist/commonjs/customHooks/performanceTracker.js +541 -0
- package/dist/commonjs/helpers/index.d.ts +15 -0
- package/dist/commonjs/helpers/index.js +112 -1
- package/dist/commonjs/i18n/locales/en.json +225 -2
- package/dist/commonjs/styles/AppColors.d.ts +110 -0
- package/dist/commonjs/styles/AppColors.js +114 -0
- package/dist/esm/components/AnalyticsDetail.js +5 -3
- package/dist/esm/components/AnalyticsEventCard.d.ts +0 -1
- package/dist/esm/components/AnalyticsEventCard.js +85 -95
- package/dist/esm/components/Inspector/BundleTab.js +489 -654
- package/dist/esm/components/Inspector/PerformanceTab.js +185 -244
- package/dist/esm/components/Inspector/ReduxDetail.js +2 -2
- package/dist/esm/components/Inspector/ReduxTab.js +3 -3
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/bundleAnalyzer.d.ts +115 -0
- package/dist/esm/customHooks/bundleAnalyzer.js +554 -0
- package/dist/esm/customHooks/performanceTracker.d.ts +84 -0
- package/dist/esm/customHooks/performanceTracker.js +537 -0
- package/dist/esm/helpers/index.d.ts +15 -0
- package/dist/esm/helpers/index.js +107 -0
- package/dist/esm/i18n/locales/en.json +225 -2
- package/dist/esm/styles/AppColors.d.ts +110 -0
- package/dist/esm/styles/AppColors.js +114 -0
- package/package.json +1 -1
|
@@ -46,6 +46,7 @@ const AppColors_1 = require("../../styles/AppColors");
|
|
|
46
46
|
const AppFonts_1 = require("../../styles/AppFonts");
|
|
47
47
|
const NetworkIcons_1 = require("../NetworkIcons");
|
|
48
48
|
const react_native_svg_1 = __importStar(require("react-native-svg"));
|
|
49
|
+
const bundleAnalyzer_1 = require("../../customHooks/bundleAnalyzer");
|
|
49
50
|
// ─── High-Fidelity Vector Package & NPM Logos ────────────────────────────────
|
|
50
51
|
const PackageLogoRenderer = ({ name, size = 28 }) => {
|
|
51
52
|
const lowerName = name.toLowerCase();
|
|
@@ -57,13 +58,13 @@ const PackageLogoRenderer = ({ name, size = 28 }) => {
|
|
|
57
58
|
!lowerName.includes('gradient'))) {
|
|
58
59
|
return (<react_native_1.View style={[
|
|
59
60
|
bundleStyles.pkgLogoWrap,
|
|
60
|
-
{ width: size, height: size, backgroundColor:
|
|
61
|
+
{ width: size, height: size, backgroundColor: AppColors_1.AppColors.npmDark },
|
|
61
62
|
]}>
|
|
62
63
|
<react_native_svg_1.default width={size - 6} height={size - 6} viewBox="0 0 100 100" fill="none">
|
|
63
|
-
<react_native_svg_1.Circle cx="50" cy="50" r="9" fill=
|
|
64
|
-
<react_native_svg_1.Ellipse cx="50" cy="50" rx="42" ry="16" stroke=
|
|
65
|
-
<react_native_svg_1.Ellipse cx="50" cy="50" rx="42" ry="16" stroke=
|
|
66
|
-
<react_native_svg_1.Ellipse cx="50" cy="50" rx="42" ry="16" stroke=
|
|
64
|
+
<react_native_svg_1.Circle cx="50" cy="50" r="9" fill={AppColors_1.AppColors.reactCyan}/>
|
|
65
|
+
<react_native_svg_1.Ellipse cx="50" cy="50" rx="42" ry="16" stroke={AppColors_1.AppColors.reactCyan} strokeWidth="6"/>
|
|
66
|
+
<react_native_svg_1.Ellipse cx="50" cy="50" rx="42" ry="16" stroke={AppColors_1.AppColors.reactCyan} strokeWidth="6" transform="rotate(60 50 50)"/>
|
|
67
|
+
<react_native_svg_1.Ellipse cx="50" cy="50" rx="42" ry="16" stroke={AppColors_1.AppColors.reactCyan} strokeWidth="6" transform="rotate(120 50 50)"/>
|
|
67
68
|
</react_native_svg_1.default>
|
|
68
69
|
</react_native_1.View>);
|
|
69
70
|
}
|
|
@@ -71,12 +72,12 @@ const PackageLogoRenderer = ({ name, size = 28 }) => {
|
|
|
71
72
|
if (lowerName.includes('navigation')) {
|
|
72
73
|
return (<react_native_1.View style={[
|
|
73
74
|
bundleStyles.pkgLogoWrap,
|
|
74
|
-
{ width: size, height: size, backgroundColor:
|
|
75
|
+
{ width: size, height: size, backgroundColor: AppColors_1.AppColors.hermesPurple },
|
|
75
76
|
]}>
|
|
76
77
|
<react_native_svg_1.default width={size - 8} height={size - 8} viewBox="0 0 100 100" fill="none">
|
|
77
|
-
<react_native_svg_1.Circle cx="50" cy="50" r="38" stroke=
|
|
78
|
-
<react_native_svg_1.Path d="M50 20 L68 50 L50 80 L32 50 Z" fill=
|
|
79
|
-
<react_native_svg_1.Circle cx="50" cy="50" r="6" fill=
|
|
78
|
+
<react_native_svg_1.Circle cx="50" cy="50" r="38" stroke={AppColors_1.AppColors.white} strokeWidth="8"/>
|
|
79
|
+
<react_native_svg_1.Path d="M50 20 L68 50 L50 80 L32 50 Z" fill={AppColors_1.AppColors.reactCyan}/>
|
|
80
|
+
<react_native_svg_1.Circle cx="50" cy="50" r="6" fill={AppColors_1.AppColors.white}/>
|
|
80
81
|
</react_native_svg_1.default>
|
|
81
82
|
</react_native_1.View>);
|
|
82
83
|
}
|
|
@@ -84,13 +85,13 @@ const PackageLogoRenderer = ({ name, size = 28 }) => {
|
|
|
84
85
|
if (lowerName.includes('svg')) {
|
|
85
86
|
return (<react_native_1.View style={[
|
|
86
87
|
bundleStyles.pkgLogoWrap,
|
|
87
|
-
{ width: size, height: size, backgroundColor:
|
|
88
|
+
{ width: size, height: size, backgroundColor: AppColors_1.AppColors.pink400 },
|
|
88
89
|
]}>
|
|
89
90
|
<react_native_svg_1.default width={size - 8} height={size - 8} viewBox="0 0 100 100" fill="none">
|
|
90
|
-
<react_native_svg_1.Path d="M20 75 C35 25, 65 25, 80 75" stroke=
|
|
91
|
-
<react_native_svg_1.Circle cx="20" cy="75" r="8" fill=
|
|
92
|
-
<react_native_svg_1.Circle cx="80" cy="75" r="8" fill=
|
|
93
|
-
<react_native_svg_1.Circle cx="50" cy="38" r="7" fill="#FCE7F3" stroke=
|
|
91
|
+
<react_native_svg_1.Path d="M20 75 C35 25, 65 25, 80 75" stroke={AppColors_1.AppColors.white} strokeWidth="10" strokeLinecap="round"/>
|
|
92
|
+
<react_native_svg_1.Circle cx="20" cy="75" r="8" fill={AppColors_1.AppColors.white}/>
|
|
93
|
+
<react_native_svg_1.Circle cx="80" cy="75" r="8" fill={AppColors_1.AppColors.white}/>
|
|
94
|
+
<react_native_svg_1.Circle cx="50" cy="38" r="7" fill="#FCE7F3" stroke={AppColors_1.AppColors.white} strokeWidth="3"/>
|
|
94
95
|
</react_native_svg_1.default>
|
|
95
96
|
</react_native_1.View>);
|
|
96
97
|
}
|
|
@@ -98,11 +99,11 @@ const PackageLogoRenderer = ({ name, size = 28 }) => {
|
|
|
98
99
|
if (lowerName.includes('axios')) {
|
|
99
100
|
return (<react_native_1.View style={[
|
|
100
101
|
bundleStyles.pkgLogoWrap,
|
|
101
|
-
{ width: size, height: size, backgroundColor:
|
|
102
|
+
{ width: size, height: size, backgroundColor: AppColors_1.AppColors.expoViolet },
|
|
102
103
|
]}>
|
|
103
104
|
<react_native_svg_1.default width={size - 6} height={size - 6} viewBox="0 0 100 100" fill="none">
|
|
104
|
-
<react_native_svg_1.Path d="M22 75 L50 20 L78 75 M33 58 L67 58" stroke=
|
|
105
|
-
<react_native_svg_1.Circle cx="50" cy="20" r="7" fill=
|
|
105
|
+
<react_native_svg_1.Path d="M22 75 L50 20 L78 75 M33 58 L67 58" stroke={AppColors_1.AppColors.white} strokeWidth="12" strokeLinecap="round" strokeLinejoin="round"/>
|
|
106
|
+
<react_native_svg_1.Circle cx="50" cy="20" r="7" fill={AppColors_1.AppColors.reactCyan}/>
|
|
106
107
|
</react_native_svg_1.default>
|
|
107
108
|
</react_native_1.View>);
|
|
108
109
|
}
|
|
@@ -110,11 +111,11 @@ const PackageLogoRenderer = ({ name, size = 28 }) => {
|
|
|
110
111
|
if (lowerName.includes('screens') || lowerName.includes('software-mansion')) {
|
|
111
112
|
return (<react_native_1.View style={[
|
|
112
113
|
bundleStyles.pkgLogoWrap,
|
|
113
|
-
{ width: size, height: size, backgroundColor:
|
|
114
|
+
{ width: size, height: size, backgroundColor: AppColors_1.AppColors.reanimatedNavy },
|
|
114
115
|
]}>
|
|
115
116
|
<react_native_svg_1.default width={size - 8} height={size - 8} viewBox="0 0 100 100" fill="none">
|
|
116
|
-
<react_native_svg_1.Path d="M50 15 L88 35 L50 55 L12 35 Z" fill=
|
|
117
|
-
<react_native_svg_1.Path d="M12 50 L50 70 L88 50" stroke=
|
|
117
|
+
<react_native_svg_1.Path d="M50 15 L88 35 L50 55 L12 35 Z" fill={AppColors_1.AppColors.sky400}/>
|
|
118
|
+
<react_native_svg_1.Path d="M12 50 L50 70 L88 50" stroke={AppColors_1.AppColors.white} strokeWidth="8" strokeLinecap="round"/>
|
|
118
119
|
<react_native_svg_1.Path d="M12 65 L50 85 L88 65" stroke="#93C5FD" strokeWidth="8" strokeLinecap="round"/>
|
|
119
120
|
</react_native_svg_1.default>
|
|
120
121
|
</react_native_1.View>);
|
|
@@ -123,7 +124,7 @@ const PackageLogoRenderer = ({ name, size = 28 }) => {
|
|
|
123
124
|
if (lowerName.includes('gradient')) {
|
|
124
125
|
return (<react_native_1.View style={[
|
|
125
126
|
bundleStyles.pkgLogoWrap,
|
|
126
|
-
{ width: size, height: size, backgroundColor:
|
|
127
|
+
{ width: size, height: size, backgroundColor: AppColors_1.AppColors.rose600 },
|
|
127
128
|
]}>
|
|
128
129
|
<react_native_svg_1.default width={size - 4} height={size - 4} viewBox="0 0 100 100" fill="none">
|
|
129
130
|
<react_native_svg_1.Defs>
|
|
@@ -141,23 +142,23 @@ const PackageLogoRenderer = ({ name, size = 28 }) => {
|
|
|
141
142
|
if (lowerName.includes('i18n')) {
|
|
142
143
|
return (<react_native_1.View style={[
|
|
143
144
|
bundleStyles.pkgLogoWrap,
|
|
144
|
-
{ width: size, height: size, backgroundColor:
|
|
145
|
+
{ width: size, height: size, backgroundColor: AppColors_1.AppColors.emerald600 },
|
|
145
146
|
]}>
|
|
146
147
|
<react_native_svg_1.default width={size - 8} height={size - 8} viewBox="0 0 100 100" fill="none">
|
|
147
|
-
<react_native_svg_1.Circle cx="50" cy="50" r="38" stroke=
|
|
148
|
-
<react_native_svg_1.Ellipse cx="50" cy="50" rx="18" ry="38" stroke=
|
|
149
|
-
<react_native_svg_1.Path d="M14 50 L86 50" stroke=
|
|
148
|
+
<react_native_svg_1.Circle cx="50" cy="50" r="38" stroke={AppColors_1.AppColors.white} strokeWidth="8"/>
|
|
149
|
+
<react_native_svg_1.Ellipse cx="50" cy="50" rx="18" ry="38" stroke={AppColors_1.AppColors.white} strokeWidth="6"/>
|
|
150
|
+
<react_native_svg_1.Path d="M14 50 L86 50" stroke={AppColors_1.AppColors.white} strokeWidth="7"/>
|
|
150
151
|
</react_native_svg_1.default>
|
|
151
152
|
</react_native_1.View>);
|
|
152
153
|
}
|
|
153
154
|
// 8. Official Red NPM Logo Box (Universal Default NPM Branding)
|
|
154
155
|
return (<react_native_1.View style={[
|
|
155
156
|
bundleStyles.pkgLogoWrap,
|
|
156
|
-
{ width: size, height: size, backgroundColor:
|
|
157
|
+
{ width: size, height: size, backgroundColor: AppColors_1.AppColors.npmRed },
|
|
157
158
|
]}>
|
|
158
159
|
<react_native_svg_1.default width={size - 4} height={size - 4} viewBox="0 0 100 100" fill="none">
|
|
159
|
-
<react_native_svg_1.Rect width="100" height="100" rx="14" fill=
|
|
160
|
-
<react_native_svg_1.Path d="M18 24 H82 V76 H50 V40 H38 V76 H18 Z" fill=
|
|
160
|
+
<react_native_svg_1.Rect width="100" height="100" rx="14" fill={AppColors_1.AppColors.npmRed}/>
|
|
161
|
+
<react_native_svg_1.Path d="M18 24 H82 V76 H50 V40 H38 V76 H18 Z" fill={AppColors_1.AppColors.white}/>
|
|
161
162
|
</react_native_svg_1.default>
|
|
162
163
|
</react_native_1.View>);
|
|
163
164
|
};
|
|
@@ -169,25 +170,25 @@ const MediaPreviewThumbnail = ({ file }) => {
|
|
|
169
170
|
return (<react_native_1.View style={[
|
|
170
171
|
bundleStyles.mediaThumbWrap,
|
|
171
172
|
{
|
|
172
|
-
backgroundColor:
|
|
173
|
+
backgroundColor: AppColors_1.AppColors.errorCardBg,
|
|
173
174
|
alignItems: 'center',
|
|
174
175
|
justifyContent: 'center',
|
|
175
|
-
borderColor:
|
|
176
|
+
borderColor: AppColors_1.AppColors.errorBorder,
|
|
176
177
|
},
|
|
177
178
|
]}>
|
|
178
179
|
<react_native_svg_1.default width={22} height={22} viewBox="0 0 100 100" fill="none">
|
|
179
180
|
<react_native_svg_1.Defs>
|
|
180
181
|
<react_native_svg_1.LinearGradient id="svgGradThumb" x1="0" y1="0" x2="100" y2="100" gradientUnits="userSpaceOnUse">
|
|
181
|
-
<react_native_svg_1.Stop offset="0" stopColor=
|
|
182
|
-
<react_native_svg_1.Stop offset="1" stopColor=
|
|
182
|
+
<react_native_svg_1.Stop offset="0" stopColor={AppColors_1.AppColors.rose500}/>
|
|
183
|
+
<react_native_svg_1.Stop offset="1" stopColor={AppColors_1.AppColors.rose600}/>
|
|
183
184
|
</react_native_svg_1.LinearGradient>
|
|
184
185
|
</react_native_svg_1.Defs>
|
|
185
186
|
<react_native_svg_1.Circle cx="50" cy="50" r="44" fill="url(#svgGradThumb)"/>
|
|
186
187
|
{/* Vector bezier path pen graphic */}
|
|
187
|
-
<react_native_svg_1.Path d="M25 70 C35 30, 65 30, 75 70" stroke=
|
|
188
|
-
<react_native_svg_1.Circle cx="25" cy="70" r="7" fill=
|
|
189
|
-
<react_native_svg_1.Circle cx="75" cy="70" r="7" fill=
|
|
190
|
-
<react_native_svg_1.Circle cx="50" cy="40" r="6" fill="#FFE4E6" stroke=
|
|
188
|
+
<react_native_svg_1.Path d="M25 70 C35 30, 65 30, 75 70" stroke={AppColors_1.AppColors.white} strokeWidth="8" strokeLinecap="round"/>
|
|
189
|
+
<react_native_svg_1.Circle cx="25" cy="70" r="7" fill={AppColors_1.AppColors.white}/>
|
|
190
|
+
<react_native_svg_1.Circle cx="75" cy="70" r="7" fill={AppColors_1.AppColors.white}/>
|
|
191
|
+
<react_native_svg_1.Circle cx="50" cy="40" r="6" fill="#FFE4E6" stroke={AppColors_1.AppColors.white} strokeWidth="2"/>
|
|
191
192
|
</react_native_svg_1.default>
|
|
192
193
|
</react_native_1.View>);
|
|
193
194
|
}
|
|
@@ -285,7 +286,7 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, collapsedFolde
|
|
|
285
286
|
<HighlightText_1.default text={node.name + '/'} search={search} style={bundleStyles.treeFolderName} highlightStyle={bundleStyles.searchHighlight}/>
|
|
286
287
|
<react_native_1.View style={bundleStyles.treeCountBadge}>
|
|
287
288
|
<react_native_1.Text style={bundleStyles.treeCountBadgeText}>
|
|
288
|
-
{node.fileCount} {node.fileCount === 1 ? 'file' : 'files'}
|
|
289
|
+
{node.fileCount} {node.fileCount === 1 ? (0, i18n_1.t)('bundle.file') : (0, i18n_1.t)('bundle.files')}
|
|
289
290
|
</react_native_1.Text>
|
|
290
291
|
</react_native_1.View>
|
|
291
292
|
</react_native_1.View>
|
|
@@ -293,14 +294,14 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, collapsedFolde
|
|
|
293
294
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
294
295
|
<react_native_1.Text style={bundleStyles.treeFolderSize}>
|
|
295
296
|
{node.sizeKb >= 1024
|
|
296
|
-
?
|
|
297
|
-
:
|
|
297
|
+
? (0, i18n_1.t)('bundle.fileSizeMb', { size: (node.sizeKb / 1024).toFixed(2) })
|
|
298
|
+
: (0, i18n_1.t)('bundle.fileSizeKb', { size: node.sizeKb })}
|
|
298
299
|
</react_native_1.Text>
|
|
299
300
|
<CopyButton_1.default value={() => ({
|
|
300
301
|
folder: node.fullPath,
|
|
301
302
|
sizeKb: node.sizeKb,
|
|
302
303
|
fileCount: node.fileCount,
|
|
303
|
-
})} label={
|
|
304
|
+
})} label={(0, i18n_1.t)('bundle.copyFileInfo', { name: node.name })}/>
|
|
304
305
|
</react_native_1.View>
|
|
305
306
|
</TouchableScale_1.default>
|
|
306
307
|
|
|
@@ -329,9 +330,9 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, collapsedFolde
|
|
|
329
330
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
|
|
330
331
|
<HighlightText_1.default text={file.name} search={search} style={bundleStyles.fileName} highlightStyle={bundleStyles.searchHighlight}/>
|
|
331
332
|
{isUnused ? (<react_native_1.View style={bundleStyles.unusedBadge}>
|
|
332
|
-
<react_native_1.Text style={bundleStyles.unusedBadgeText}
|
|
333
|
+
<react_native_1.Text style={bundleStyles.unusedBadgeText}>{(0, i18n_1.t)('bundle.notConsumed')}</react_native_1.Text>
|
|
333
334
|
</react_native_1.View>) : (<react_native_1.View style={bundleStyles.consumedBadge}>
|
|
334
|
-
<react_native_1.Text style={bundleStyles.consumedBadgeText}
|
|
335
|
+
<react_native_1.Text style={bundleStyles.consumedBadgeText}>{(0, i18n_1.t)('bundle.consumed')}</react_native_1.Text>
|
|
335
336
|
</react_native_1.View>)}
|
|
336
337
|
</react_native_1.View>
|
|
337
338
|
<react_native_1.Text style={bundleStyles.filePath} numberOfLines={1}>
|
|
@@ -341,14 +342,14 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, collapsedFolde
|
|
|
341
342
|
|
|
342
343
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
343
344
|
<react_native_1.View style={bundleStyles.fileSizeBox}>
|
|
344
|
-
<react_native_1.Text style={[bundleStyles.fileSizeKb, isUnused && { color:
|
|
345
|
+
<react_native_1.Text style={[bundleStyles.fileSizeKb, isUnused && { color: AppColors_1.AppColors.amber800Warm }]}>
|
|
345
346
|
{file.sizeKb >= 1024
|
|
346
|
-
?
|
|
347
|
-
:
|
|
347
|
+
? (0, i18n_1.t)('bundle.fileSizeMb', { size: (file.sizeKb / 1024).toFixed(2) })
|
|
348
|
+
: (0, i18n_1.t)('bundle.fileSizeKb', { size: file.sizeKb })}
|
|
348
349
|
</react_native_1.Text>
|
|
349
350
|
<react_native_1.Text style={bundleStyles.filePercent}>{pctOfTotal}%</react_native_1.Text>
|
|
350
351
|
</react_native_1.View>
|
|
351
|
-
<CopyButton_1.default value={() => file} label=
|
|
352
|
+
<CopyButton_1.default value={() => file} label={(0, i18n_1.t)('bundle.fileDetailsJson')}/>
|
|
352
353
|
</react_native_1.View>
|
|
353
354
|
</react_native_1.View>
|
|
354
355
|
|
|
@@ -361,9 +362,9 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, collapsedFolde
|
|
|
361
362
|
]}>
|
|
362
363
|
<react_native_1.Text style={[
|
|
363
364
|
bundleStyles.adviceText,
|
|
364
|
-
file.status === 'warning' && { color:
|
|
365
|
-
file.status === 'optimal' && { color:
|
|
366
|
-
isUnused && { color:
|
|
365
|
+
file.status === 'warning' && { color: AppColors_1.AppColors.amber800Warm },
|
|
366
|
+
file.status === 'optimal' && { color: AppColors_1.AppColors.emerald700 },
|
|
367
|
+
isUnused && { color: AppColors_1.AppColors.red600 },
|
|
367
368
|
]}>
|
|
368
369
|
{isUnused ? '🗑️ ' : file.status === 'warning' ? '💡 ' : '✨ '}
|
|
369
370
|
{file.advice}
|
|
@@ -371,417 +372,48 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, collapsedFolde
|
|
|
371
372
|
</react_native_1.View>)}
|
|
372
373
|
</react_native_1.View>);
|
|
373
374
|
};
|
|
374
|
-
// ─── Sample Bundle Files Data ────────────────────────────────────────────────
|
|
375
|
-
const BUNDLE_FILES_DATA = [
|
|
376
|
-
// ── Images & Media ──
|
|
377
|
-
{
|
|
378
|
-
id: 'img-1',
|
|
379
|
-
name: 'banner_dark.png',
|
|
380
|
-
path: 'assets/images/banner_dark.png',
|
|
381
|
-
ext: 'PNG',
|
|
382
|
-
category: 'image',
|
|
383
|
-
sizeKb: 460,
|
|
384
|
-
meta: '1200×630px @2x • Raster Image',
|
|
385
|
-
color: '#EC4899',
|
|
386
|
-
status: 'warning',
|
|
387
|
-
advice: 'Convert to .webp to save ~65% (160 KB)',
|
|
388
|
-
previewUri: 'https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=200&auto=format&fit=crop&q=80',
|
|
389
|
-
},
|
|
390
|
-
{
|
|
391
|
-
id: 'img-2',
|
|
392
|
-
name: 'banner_light.svg',
|
|
393
|
-
path: 'assets/images/banner_light.svg',
|
|
394
|
-
ext: 'SVG',
|
|
395
|
-
category: 'image',
|
|
396
|
-
sizeKb: 34,
|
|
397
|
-
meta: 'Scalable Vector Graphic',
|
|
398
|
-
color: '#F43F5E',
|
|
399
|
-
status: 'optimal',
|
|
400
|
-
advice: 'Optimal vector format for sharp rendering',
|
|
401
|
-
previewUri: 'https://images.unsplash.com/photo-1579783902614-a3fb3927b675?w=200&auto=format&fit=crop&q=80',
|
|
402
|
-
},
|
|
403
|
-
{
|
|
404
|
-
id: 'img-3',
|
|
405
|
-
name: 'logo_hero@3x.png',
|
|
406
|
-
path: 'assets/brand/logo_hero@3x.png',
|
|
407
|
-
ext: 'PNG',
|
|
408
|
-
category: 'image',
|
|
409
|
-
sizeKb: 285,
|
|
410
|
-
meta: '768×768px @3x Retina Asset',
|
|
411
|
-
color: '#EC4899',
|
|
412
|
-
status: 'warning',
|
|
413
|
-
advice: 'High density PNG. Consider tintable SVG vector',
|
|
414
|
-
previewUri: 'https://images.unsplash.com/photo-1634017839464-5c339ebe3cb4?w=200&auto=format&fit=crop&q=80',
|
|
415
|
-
},
|
|
416
|
-
{
|
|
417
|
-
id: 'img-4',
|
|
418
|
-
name: 'avatar_placeholder.webp',
|
|
419
|
-
path: 'assets/placeholders/avatar_placeholder.webp',
|
|
420
|
-
ext: 'WEBP',
|
|
421
|
-
category: 'image',
|
|
422
|
-
sizeKb: 28,
|
|
423
|
-
meta: '256×256px Lossy WebP',
|
|
424
|
-
color: '#F472B6',
|
|
425
|
-
status: 'warning',
|
|
426
|
-
advice: 'Unused in bundle: 0 active imports detected (28 KB unused)',
|
|
427
|
-
previewUri: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=200&auto=format&fit=crop&q=80',
|
|
428
|
-
isConsumed: false,
|
|
429
|
-
},
|
|
430
|
-
{
|
|
431
|
-
id: 'img-5',
|
|
432
|
-
name: 'walkthrough_thumb.jpg',
|
|
433
|
-
path: 'assets/previews/walkthrough_thumb.jpg',
|
|
434
|
-
ext: 'JPG',
|
|
435
|
-
category: 'image',
|
|
436
|
-
sizeKb: 175,
|
|
437
|
-
meta: '1080×600px Progressive JPEG',
|
|
438
|
-
color: '#FB7185',
|
|
439
|
-
status: 'warning',
|
|
440
|
-
advice: 'Dead asset: 0 component references (175 KB unused)',
|
|
441
|
-
previewUri: 'https://images.unsplash.com/photo-1550745165-9bc0b252726f?w=200&auto=format&fit=crop&q=80',
|
|
442
|
-
isConsumed: false,
|
|
443
|
-
},
|
|
444
|
-
// ── TypeScript & JSX ──
|
|
445
|
-
{
|
|
446
|
-
id: 'ts-1',
|
|
447
|
-
name: 'LogDetail.tsx',
|
|
448
|
-
path: 'src/components/Inspector/LogDetail.tsx',
|
|
449
|
-
ext: 'TSX',
|
|
450
|
-
category: 'typescript',
|
|
451
|
-
sizeKb: 44,
|
|
452
|
-
meta: '1,238 lines • React Component',
|
|
453
|
-
color: '#38BDF8',
|
|
454
|
-
status: 'optimal',
|
|
455
|
-
advice: 'Clean React.memo and useCallback optimization',
|
|
456
|
-
},
|
|
457
|
-
{
|
|
458
|
-
id: 'ts-2',
|
|
459
|
-
name: 'ReduxDetail.tsx',
|
|
460
|
-
path: 'src/components/Inspector/ReduxDetail.tsx',
|
|
461
|
-
ext: 'TSX',
|
|
462
|
-
category: 'typescript',
|
|
463
|
-
sizeKb: 38,
|
|
464
|
-
meta: '680 lines • Slice state tree & action timeline',
|
|
465
|
-
color: '#38BDF8',
|
|
466
|
-
status: 'optimal',
|
|
467
|
-
advice: 'Multi-tab subview with live state diffing',
|
|
468
|
-
},
|
|
469
|
-
{
|
|
470
|
-
id: 'ts-3',
|
|
471
|
-
name: 'NetworkTab.tsx',
|
|
472
|
-
path: 'src/components/Inspector/NetworkTab.tsx',
|
|
473
|
-
ext: 'TSX',
|
|
474
|
-
category: 'typescript',
|
|
475
|
-
sizeKb: 15,
|
|
476
|
-
meta: '486 lines • Network request virtualization list',
|
|
477
|
-
color: '#0EA5E9',
|
|
478
|
-
status: 'optimal',
|
|
479
|
-
advice: 'FlatList windowSize=7 tuned for 60fps',
|
|
480
|
-
},
|
|
481
|
-
{
|
|
482
|
-
id: 'ts-4',
|
|
483
|
-
name: 'SettingsPanel.tsx',
|
|
484
|
-
path: 'src/components/Inspector/SettingsPanel.tsx',
|
|
485
|
-
ext: 'TSX',
|
|
486
|
-
category: 'typescript',
|
|
487
|
-
sizeKb: 65,
|
|
488
|
-
meta: '1,845 lines • Preferences & storage manager',
|
|
489
|
-
color: '#38BDF8',
|
|
490
|
-
status: 'info',
|
|
491
|
-
advice: 'Self-contained settings subviews',
|
|
492
|
-
},
|
|
493
|
-
{
|
|
494
|
-
id: 'ts-5',
|
|
495
|
-
name: 'consoleLogger.ts',
|
|
496
|
-
path: 'src/customHooks/consoleLogger.ts',
|
|
497
|
-
ext: 'TS',
|
|
498
|
-
category: 'typescript',
|
|
499
|
-
sizeKb: 12,
|
|
500
|
-
meta: '360 lines • Metro symbolication bridge',
|
|
501
|
-
color: '#0284C7',
|
|
502
|
-
status: 'optimal',
|
|
503
|
-
advice: 'Zero-overhead in-memory stack capture',
|
|
504
|
-
},
|
|
505
|
-
{
|
|
506
|
-
id: 'ts-6',
|
|
507
|
-
name: 'App.tsx (Playground)',
|
|
508
|
-
path: 'example/App.tsx',
|
|
509
|
-
ext: 'TSX',
|
|
510
|
-
category: 'typescript',
|
|
511
|
-
sizeKb: 25,
|
|
512
|
-
meta: '820 lines • Interactive test scenarios',
|
|
513
|
-
color: '#38BDF8',
|
|
514
|
-
status: 'optimal',
|
|
515
|
-
advice: 'Sample harness for logs, APIs, and Redux',
|
|
516
|
-
},
|
|
517
|
-
// ── JavaScript & Node Modules ──
|
|
518
|
-
{
|
|
519
|
-
id: 'js-1',
|
|
520
|
-
name: 'react-native/Libraries/Renderer',
|
|
521
|
-
path: 'node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js',
|
|
522
|
-
ext: 'JS',
|
|
523
|
-
category: 'javascript',
|
|
524
|
-
sizeKb: 480,
|
|
525
|
-
meta: 'Fabric & Paper UI reconciler bundle',
|
|
526
|
-
color: '#6366F1',
|
|
527
|
-
status: 'optimal',
|
|
528
|
-
advice: 'AOT compiled with Hermes Bytecode',
|
|
529
|
-
},
|
|
530
|
-
{
|
|
531
|
-
id: 'js-2',
|
|
532
|
-
name: '@react-navigation/native-stack',
|
|
533
|
-
path: 'node_modules/@react-navigation/native-stack/lib/module/index.js',
|
|
534
|
-
ext: 'JS',
|
|
535
|
-
category: 'javascript',
|
|
536
|
-
sizeKb: 195,
|
|
537
|
-
meta: 'Native screen animation & transition engine',
|
|
538
|
-
color: '#818CF8',
|
|
539
|
-
status: 'optimal',
|
|
540
|
-
advice: 'Optimized modular ES bundle',
|
|
541
|
-
},
|
|
542
|
-
{
|
|
543
|
-
id: 'js-3',
|
|
544
|
-
name: 'axios/dist/esm/axios.js',
|
|
545
|
-
path: 'node_modules/axios/dist/esm/axios.js',
|
|
546
|
-
ext: 'JS',
|
|
547
|
-
category: 'javascript',
|
|
548
|
-
sizeKb: 88,
|
|
549
|
-
meta: 'HTTP client core with interceptors',
|
|
550
|
-
color: '#F59E0B',
|
|
551
|
-
status: 'optimal',
|
|
552
|
-
advice: 'Standard lightweight network adapter',
|
|
553
|
-
},
|
|
554
|
-
{
|
|
555
|
-
id: 'js-4',
|
|
556
|
-
name: 'react-native-svg',
|
|
557
|
-
path: 'node_modules/react-native-svg/lib/module/index.js',
|
|
558
|
-
ext: 'JS',
|
|
559
|
-
category: 'javascript',
|
|
560
|
-
sizeKb: 140,
|
|
561
|
-
meta: 'Native SVG drawing and vector paths',
|
|
562
|
-
color: '#4F46E5',
|
|
563
|
-
status: 'optimal',
|
|
564
|
-
advice: 'Native Fabric/Paper vector bridge',
|
|
565
|
-
},
|
|
566
|
-
// ── Fonts & Typography ──
|
|
567
|
-
{
|
|
568
|
-
id: 'font-1',
|
|
569
|
-
name: 'Inter-Bold.ttf',
|
|
570
|
-
path: 'fonts/Inter-Bold.ttf',
|
|
571
|
-
ext: 'TTF',
|
|
572
|
-
category: 'font',
|
|
573
|
-
sizeKb: 165,
|
|
574
|
-
meta: 'Custom UI Font • Full Latin Charset (480 glyphs)',
|
|
575
|
-
color: '#8B5CF6',
|
|
576
|
-
status: 'info',
|
|
577
|
-
advice: 'High readability modern typography',
|
|
578
|
-
},
|
|
579
|
-
{
|
|
580
|
-
id: 'font-2',
|
|
581
|
-
name: 'Inter-Regular.ttf',
|
|
582
|
-
path: 'fonts/Inter-Regular.ttf',
|
|
583
|
-
ext: 'TTF',
|
|
584
|
-
category: 'font',
|
|
585
|
-
sizeKb: 160,
|
|
586
|
-
meta: 'Custom Body Font • 400 Weight (480 glyphs)',
|
|
587
|
-
color: '#8B5CF6',
|
|
588
|
-
status: 'info',
|
|
589
|
-
advice: 'Applied across inspector UI cards and text',
|
|
590
|
-
},
|
|
591
|
-
{
|
|
592
|
-
id: 'font-3',
|
|
593
|
-
name: 'JetBrainsMono-Regular.ttf',
|
|
594
|
-
path: 'fonts/JetBrainsMono-Regular.ttf',
|
|
595
|
-
ext: 'TTF',
|
|
596
|
-
category: 'font',
|
|
597
|
-
sizeKb: 95,
|
|
598
|
-
meta: 'Monospace Code Font • Raw / Table / Stack Traces',
|
|
599
|
-
color: '#A855F7',
|
|
600
|
-
status: 'optimal',
|
|
601
|
-
advice: 'Crisp font for code snippets and stack traces',
|
|
602
|
-
},
|
|
603
|
-
// ── JSON & Localizations ──
|
|
604
|
-
{
|
|
605
|
-
id: 'json-1',
|
|
606
|
-
name: 'en.json (i18n Translations)',
|
|
607
|
-
path: 'src/i18n/locales/en.json',
|
|
608
|
-
ext: 'JSON',
|
|
609
|
-
category: 'json',
|
|
610
|
-
sizeKb: 18,
|
|
611
|
-
meta: '124 localization translation keys',
|
|
612
|
-
color: '#10B981',
|
|
613
|
-
status: 'optimal',
|
|
614
|
-
advice: 'Static JSON locale dictionary',
|
|
615
|
-
},
|
|
616
|
-
{
|
|
617
|
-
id: 'json-2',
|
|
618
|
-
name: 'package.json',
|
|
619
|
-
path: 'package.json',
|
|
620
|
-
ext: 'JSON',
|
|
621
|
-
category: 'json',
|
|
622
|
-
sizeKb: 3,
|
|
623
|
-
meta: 'Manifest & peer dependencies config',
|
|
624
|
-
color: '#059669',
|
|
625
|
-
status: 'optimal',
|
|
626
|
-
advice: 'Stripped during production bundle export',
|
|
627
|
-
},
|
|
628
|
-
];
|
|
629
|
-
// ─── Packages / Node Modules Breakdown Data ──────────────────────────────────
|
|
630
|
-
const BUNDLE_PACKAGES_DATA = [
|
|
631
|
-
{
|
|
632
|
-
id: 'pkg-1',
|
|
633
|
-
name: 'react-native',
|
|
634
|
-
version: '0.85.3',
|
|
635
|
-
latestVersion: '0.85.3',
|
|
636
|
-
sizeKb: 680,
|
|
637
|
-
percentage: 38.5,
|
|
638
|
-
type: 'direct',
|
|
639
|
-
category: 'core',
|
|
640
|
-
color: '#38BDF8',
|
|
641
|
-
description: 'React Native runtime, Fabric UI engine, Native Bridge, and Turbomodules.',
|
|
642
|
-
logoUri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/512px-React-icon.svg.png',
|
|
643
|
-
lastActive: '3 days ago',
|
|
644
|
-
npmUrl: 'https://www.npmjs.com/package/react-native',
|
|
645
|
-
isDeprecated: false,
|
|
646
|
-
},
|
|
647
|
-
{
|
|
648
|
-
id: 'pkg-2',
|
|
649
|
-
name: '@react-navigation/native-stack',
|
|
650
|
-
version: '^7.16.0',
|
|
651
|
-
latestVersion: '7.16.0',
|
|
652
|
-
sizeKb: 245,
|
|
653
|
-
percentage: 13.9,
|
|
654
|
-
type: 'direct',
|
|
655
|
-
category: 'navigation',
|
|
656
|
-
color: '#818CF8',
|
|
657
|
-
description: 'Native screen router, UIViewController / Fragment animations and transitions.',
|
|
658
|
-
logoUri: 'https://reactnavigation.org/img/spiro.svg',
|
|
659
|
-
lastActive: '1 week ago',
|
|
660
|
-
npmUrl: 'https://www.npmjs.com/package/@react-navigation/native-stack',
|
|
661
|
-
isDeprecated: false,
|
|
662
|
-
},
|
|
663
|
-
{
|
|
664
|
-
id: 'pkg-3',
|
|
665
|
-
name: 'react',
|
|
666
|
-
version: '19.2.3',
|
|
667
|
-
latestVersion: '19.2.3',
|
|
668
|
-
sizeKb: 185,
|
|
669
|
-
percentage: 10.5,
|
|
670
|
-
type: 'direct',
|
|
671
|
-
category: 'core',
|
|
672
|
-
color: '#06B6D4',
|
|
673
|
-
description: 'React core virtual DOM reconciler, hooks engine, and JSX runtime.',
|
|
674
|
-
logoUri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/512px-React-icon.svg.png',
|
|
675
|
-
lastActive: '5 days ago',
|
|
676
|
-
npmUrl: 'https://www.npmjs.com/package/react',
|
|
677
|
-
isDeprecated: false,
|
|
678
|
-
},
|
|
679
|
-
{
|
|
680
|
-
id: 'pkg-4',
|
|
681
|
-
name: 'react-native-svg',
|
|
682
|
-
version: '^15.15.5',
|
|
683
|
-
latestVersion: '15.16.0',
|
|
684
|
-
sizeKb: 140,
|
|
685
|
-
percentage: 7.9,
|
|
686
|
-
type: 'direct',
|
|
687
|
-
category: 'ui',
|
|
688
|
-
color: '#F472B6',
|
|
689
|
-
description: 'Scalable Vector Graphics XML parser and native canvas path rasterizer.',
|
|
690
|
-
logoUri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/SVG_logo.svg/512px-SVG_logo.svg.png',
|
|
691
|
-
lastActive: '2 days ago',
|
|
692
|
-
npmUrl: 'https://www.npmjs.com/package/react-native-svg',
|
|
693
|
-
isDeprecated: false,
|
|
694
|
-
},
|
|
695
|
-
{
|
|
696
|
-
id: 'pkg-5',
|
|
697
|
-
name: 'react-native-screens',
|
|
698
|
-
version: '^4.25.2',
|
|
699
|
-
latestVersion: '4.25.2',
|
|
700
|
-
sizeKb: 110,
|
|
701
|
-
percentage: 6.2,
|
|
702
|
-
type: 'transitive',
|
|
703
|
-
category: 'navigation',
|
|
704
|
-
color: '#A78BFA',
|
|
705
|
-
description: 'Native navigation container primitives for iOS and Android memory management.',
|
|
706
|
-
logoUri: 'https://reactnavigation.org/img/spiro.svg',
|
|
707
|
-
lastActive: '2 weeks ago',
|
|
708
|
-
npmUrl: 'https://www.npmjs.com/package/react-native-screens',
|
|
709
|
-
isDeprecated: false,
|
|
710
|
-
},
|
|
711
|
-
{
|
|
712
|
-
id: 'pkg-6',
|
|
713
|
-
name: 'axios',
|
|
714
|
-
version: '^1.17.0',
|
|
715
|
-
latestVersion: '1.18.0',
|
|
716
|
-
sizeKb: 88,
|
|
717
|
-
percentage: 5.0,
|
|
718
|
-
type: 'direct',
|
|
719
|
-
category: 'network',
|
|
720
|
-
color: '#F59E0B',
|
|
721
|
-
description: 'HTTP client, request/response interceptors, and adapter pipelines.',
|
|
722
|
-
logoUri: 'https://axios-http.com/assets/logo.svg',
|
|
723
|
-
lastActive: '4 days ago',
|
|
724
|
-
npmUrl: 'https://www.npmjs.com/package/axios',
|
|
725
|
-
isDeprecated: false,
|
|
726
|
-
},
|
|
727
|
-
{
|
|
728
|
-
id: 'pkg-7',
|
|
729
|
-
name: 'react-native-linear-gradient',
|
|
730
|
-
version: '^2.8.3',
|
|
731
|
-
latestVersion: '2.8.3',
|
|
732
|
-
sizeKb: 45,
|
|
733
|
-
percentage: 2.5,
|
|
734
|
-
type: 'direct',
|
|
735
|
-
category: 'ui',
|
|
736
|
-
color: '#FB7185',
|
|
737
|
-
description: 'Hardware accelerated native gradient drawing shaders.',
|
|
738
|
-
logoUri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/512px-React-icon.svg.png',
|
|
739
|
-
lastActive: '2 years ago',
|
|
740
|
-
npmUrl: 'https://www.npmjs.com/package/react-native-linear-gradient',
|
|
741
|
-
isDeprecated: true,
|
|
742
|
-
deprecationReason: 'Package maintenance is in transition. Consider expo-linear-gradient or @react-native-community/linear-gradient for Fabric support.',
|
|
743
|
-
},
|
|
744
|
-
{
|
|
745
|
-
id: 'pkg-8',
|
|
746
|
-
name: 'i18next & react-i18next',
|
|
747
|
-
version: '^26.3.6',
|
|
748
|
-
latestVersion: '26.3.6',
|
|
749
|
-
sizeKb: 62,
|
|
750
|
-
percentage: 3.5,
|
|
751
|
-
type: 'direct',
|
|
752
|
-
category: 'utils',
|
|
753
|
-
color: '#10B981',
|
|
754
|
-
description: 'Internationalization framework, language interpolator, and locale switcher.',
|
|
755
|
-
logoUri: 'https://raw.githubusercontent.com/i18next/i18next/master/assets/i18next-logo.png',
|
|
756
|
-
lastActive: '6 days ago',
|
|
757
|
-
npmUrl: 'https://www.npmjs.com/package/i18next',
|
|
758
|
-
isDeprecated: false,
|
|
759
|
-
},
|
|
760
|
-
];
|
|
761
375
|
const CATEGORY_TABS = [
|
|
762
|
-
{ key: 'ALL',
|
|
763
|
-
{ key: 'UNUSED',
|
|
764
|
-
{ key: 'CONSUMED',
|
|
765
|
-
{ key: 'image',
|
|
766
|
-
{ key: 'typescript',
|
|
767
|
-
{ key: 'javascript',
|
|
768
|
-
{ key: 'font',
|
|
769
|
-
{ key: 'json',
|
|
376
|
+
{ key: 'ALL', labelKey: 'bundle.catAll', icon: '📁' },
|
|
377
|
+
{ key: 'UNUSED', labelKey: 'bundle.catUnused', icon: '🚫' },
|
|
378
|
+
{ key: 'CONSUMED', labelKey: 'bundle.catConsumed', icon: '⚡' },
|
|
379
|
+
{ key: 'image', labelKey: 'bundle.catImages', icon: '🖼️' },
|
|
380
|
+
{ key: 'typescript', labelKey: 'bundle.catTypescript', icon: '📜' },
|
|
381
|
+
{ key: 'javascript', labelKey: 'bundle.catJavascript', icon: '⚙️' },
|
|
382
|
+
{ key: 'font', labelKey: 'bundle.catFonts', icon: '🔤' },
|
|
383
|
+
{ key: 'json', labelKey: 'bundle.catJson', icon: '📄' },
|
|
770
384
|
];
|
|
771
385
|
const CATEGORY_COLORS = {
|
|
772
|
-
image: { label: 'Images & Media', color:
|
|
773
|
-
typescript: { label: 'TypeScript', color:
|
|
774
|
-
javascript: { label: 'JavaScript', color:
|
|
775
|
-
font: { label: 'Fonts', color:
|
|
776
|
-
json: { label: 'JSON / Data', color:
|
|
386
|
+
image: { label: 'Images & Media', color: AppColors_1.AppColors.pink500, bg: AppColors_1.AppColors.pink100 },
|
|
387
|
+
typescript: { label: 'TypeScript', color: AppColors_1.AppColors.sky500, bg: AppColors_1.AppColors.sky100 },
|
|
388
|
+
javascript: { label: 'JavaScript', color: AppColors_1.AppColors.indigo500, bg: AppColors_1.AppColors.indigo50 },
|
|
389
|
+
font: { label: 'Fonts', color: AppColors_1.AppColors.purple500, bg: AppColors_1.AppColors.purple100 },
|
|
390
|
+
json: { label: 'JSON / Data', color: AppColors_1.AppColors.emerald500, bg: AppColors_1.AppColors.emerald100 },
|
|
777
391
|
};
|
|
778
392
|
const BundleTab = react_1.default.memo(() => {
|
|
779
393
|
const { t } = (0, i18n_1.useTranslation)();
|
|
780
394
|
const [activeSubTab, setActiveSubTab] = (0, react_1.useState)('overview');
|
|
781
395
|
const [search, setSearch] = (0, react_1.useState)('');
|
|
782
396
|
const [activeCategory, setActiveCategory] = (0, react_1.useState)('ALL');
|
|
397
|
+
// ─── Live Host App Bundle Analysis (fetched from Metro / runtime) ─────────
|
|
398
|
+
const [analysis, setAnalysis] = (0, react_1.useState)(() => (0, bundleAnalyzer_1.getCachedBundleAnalysis)());
|
|
399
|
+
const [isAnalyzing, setIsAnalyzing] = (0, react_1.useState)(!(0, bundleAnalyzer_1.getCachedBundleAnalysis)());
|
|
400
|
+
(0, react_1.useEffect)(() => {
|
|
401
|
+
let mounted = true;
|
|
402
|
+
(0, bundleAnalyzer_1.analyzeHostAppBundle)().then(result => {
|
|
403
|
+
if (mounted) {
|
|
404
|
+
setAnalysis(result);
|
|
405
|
+
setIsAnalyzing(false);
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
return () => {
|
|
409
|
+
mounted = false;
|
|
410
|
+
};
|
|
411
|
+
}, []);
|
|
783
412
|
// Check if Hermes is running
|
|
784
413
|
const isHermes = Boolean(global.HermesInternal);
|
|
414
|
+
// Dynamic files & packages derived from the analyzed host bundle
|
|
415
|
+
const bundleFiles = (0, react_1.useMemo)(() => (analysis ? analysis.files : []), [analysis]);
|
|
416
|
+
const bundlePackages = (0, react_1.useMemo)(() => (analysis ? analysis.packages : []), [analysis]);
|
|
785
417
|
// Group summary calculations
|
|
786
418
|
const summary = (0, react_1.useMemo)(() => {
|
|
787
419
|
let imagesKb = 0;
|
|
@@ -794,7 +426,7 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
794
426
|
let jsCount = 0;
|
|
795
427
|
let fontsCount = 0;
|
|
796
428
|
let jsonCount = 0;
|
|
797
|
-
|
|
429
|
+
bundleFiles.forEach(f => {
|
|
798
430
|
if (f.category === 'image') {
|
|
799
431
|
imagesKb += f.sizeKb;
|
|
800
432
|
imagesCount++;
|
|
@@ -820,37 +452,37 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
820
452
|
return {
|
|
821
453
|
totalKb,
|
|
822
454
|
totalMb: (totalKb / 1024).toFixed(2),
|
|
823
|
-
totalCount:
|
|
455
|
+
totalCount: bundleFiles.length,
|
|
824
456
|
images: {
|
|
825
457
|
count: imagesCount,
|
|
826
458
|
kb: imagesKb,
|
|
827
|
-
pct: Number(((imagesKb / totalKb) * 100).toFixed(1)),
|
|
459
|
+
pct: totalKb ? Number(((imagesKb / totalKb) * 100).toFixed(1)) : 0,
|
|
828
460
|
},
|
|
829
461
|
ts: {
|
|
830
462
|
count: tsCount,
|
|
831
463
|
kb: tsKb,
|
|
832
|
-
pct: Number(((tsKb / totalKb) * 100).toFixed(1)),
|
|
464
|
+
pct: totalKb ? Number(((tsKb / totalKb) * 100).toFixed(1)) : 0,
|
|
833
465
|
},
|
|
834
466
|
js: {
|
|
835
467
|
count: jsCount,
|
|
836
468
|
kb: jsKb,
|
|
837
|
-
pct: Number(((jsKb / totalKb) * 100).toFixed(1)),
|
|
469
|
+
pct: totalKb ? Number(((jsKb / totalKb) * 100).toFixed(1)) : 0,
|
|
838
470
|
},
|
|
839
471
|
fonts: {
|
|
840
472
|
count: fontsCount,
|
|
841
473
|
kb: fontsKb,
|
|
842
|
-
pct: Number(((fontsKb / totalKb) * 100).toFixed(1)),
|
|
474
|
+
pct: totalKb ? Number(((fontsKb / totalKb) * 100).toFixed(1)) : 0,
|
|
843
475
|
},
|
|
844
476
|
json: {
|
|
845
477
|
count: jsonCount,
|
|
846
478
|
kb: jsonKb,
|
|
847
|
-
pct: Number(((jsonKb / totalKb) * 100).toFixed(1)),
|
|
479
|
+
pct: totalKb ? Number(((jsonKb / totalKb) * 100).toFixed(1)) : 0,
|
|
848
480
|
},
|
|
849
481
|
};
|
|
850
|
-
}, []);
|
|
482
|
+
}, [bundleFiles]);
|
|
851
483
|
// Filtered files
|
|
852
484
|
const filteredFiles = (0, react_1.useMemo)(() => {
|
|
853
|
-
return
|
|
485
|
+
return bundleFiles.filter(file => {
|
|
854
486
|
const matchSearch = !search ||
|
|
855
487
|
file.name.toLowerCase().includes(search.toLowerCase()) ||
|
|
856
488
|
file.path.toLowerCase().includes(search.toLowerCase()) ||
|
|
@@ -865,7 +497,7 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
865
497
|
: file.category === activeCategory;
|
|
866
498
|
return matchSearch && matchCategory;
|
|
867
499
|
});
|
|
868
|
-
}, [search, activeCategory]);
|
|
500
|
+
}, [search, activeCategory, bundleFiles]);
|
|
869
501
|
const filteredTotalKb = (0, react_1.useMemo)(() => {
|
|
870
502
|
return filteredFiles.reduce((acc, f) => acc + f.sizeKb, 0);
|
|
871
503
|
}, [filteredFiles]);
|
|
@@ -900,46 +532,46 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
900
532
|
// Filtered Packages
|
|
901
533
|
const filteredPackages = (0, react_1.useMemo)(() => {
|
|
902
534
|
if (!search)
|
|
903
|
-
return
|
|
535
|
+
return bundlePackages;
|
|
904
536
|
const q = search.toLowerCase();
|
|
905
|
-
return
|
|
537
|
+
return bundlePackages.filter(pkg => pkg.name.toLowerCase().includes(q) ||
|
|
906
538
|
pkg.description.toLowerCase().includes(q) ||
|
|
907
539
|
pkg.category.toLowerCase().includes(q));
|
|
908
|
-
}, [search]);
|
|
540
|
+
}, [search, bundlePackages]);
|
|
909
541
|
const packagesTotalKb = (0, react_1.useMemo)(() => {
|
|
910
542
|
return filteredPackages.reduce((acc, p) => acc + p.sizeKb, 0);
|
|
911
543
|
}, [filteredPackages]);
|
|
912
544
|
// Media files (Images + Fonts)
|
|
913
545
|
const mediaFiles = (0, react_1.useMemo)(() => {
|
|
914
|
-
return
|
|
915
|
-
}, []);
|
|
546
|
+
return bundleFiles.filter(f => f.category === 'image' || f.category === 'font');
|
|
547
|
+
}, [bundleFiles]);
|
|
916
548
|
const mediaTotalKb = (0, react_1.useMemo)(() => {
|
|
917
549
|
return mediaFiles.reduce((acc, m) => acc + m.sizeKb, 0);
|
|
918
550
|
}, [mediaFiles]);
|
|
919
551
|
const subTabs = [
|
|
920
552
|
{
|
|
921
553
|
key: 'overview',
|
|
922
|
-
label: '
|
|
554
|
+
label: t('bundle.tabOverview'),
|
|
923
555
|
icon: (isActive) => (<NetworkIcons_1.LiveStateIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={12}/>),
|
|
924
556
|
},
|
|
925
557
|
{
|
|
926
558
|
key: 'files',
|
|
927
|
-
label:
|
|
559
|
+
label: t('bundle.tabFiles', { count: bundleFiles.length }),
|
|
928
560
|
icon: (isActive) => (<NetworkIcons_1.LayersIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={12}/>),
|
|
929
561
|
},
|
|
930
562
|
{
|
|
931
563
|
key: 'packages',
|
|
932
|
-
label:
|
|
564
|
+
label: t('bundle.tabPackages', { count: bundlePackages.length }),
|
|
933
565
|
icon: (isActive) => (<NetworkIcons_1.PackageIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={12}/>),
|
|
934
566
|
},
|
|
935
567
|
{
|
|
936
568
|
key: 'media',
|
|
937
|
-
label:
|
|
569
|
+
label: t('bundle.tabMedia', { count: mediaFiles.length }),
|
|
938
570
|
icon: (isActive) => (<NetworkIcons_1.StorageIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={12}/>),
|
|
939
571
|
},
|
|
940
572
|
{
|
|
941
573
|
key: 'optimizer',
|
|
942
|
-
label: '
|
|
574
|
+
label: t('bundle.tabOptimizer'),
|
|
943
575
|
icon: (isActive) => (<NetworkIcons_1.MetadataIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={12}/>),
|
|
944
576
|
},
|
|
945
577
|
];
|
|
@@ -965,10 +597,21 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
965
597
|
</react_native_1.ScrollView>
|
|
966
598
|
</react_native_1.View>
|
|
967
599
|
|
|
600
|
+
{/* ─── Live Bundle Analysis Loading State ─── */}
|
|
601
|
+
{isAnalyzing && (<react_native_1.View style={bundleStyles.analyzingContainer}>
|
|
602
|
+
<react_native_1.ActivityIndicator size="small" color={AppColors_1.AppColors.brandPurple}/>
|
|
603
|
+
<react_native_1.Text style={bundleStyles.analyzingText}>
|
|
604
|
+
{t('bundle.analyzingTitle')}
|
|
605
|
+
</react_native_1.Text>
|
|
606
|
+
<react_native_1.Text style={bundleStyles.analyzingHint}>
|
|
607
|
+
{t('bundle.analyzingHint')}
|
|
608
|
+
</react_native_1.Text>
|
|
609
|
+
</react_native_1.View>)}
|
|
610
|
+
|
|
968
611
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
969
612
|
{/* ── 1. TAB: OVERVIEW & TREEMAP ───────────────────────────────────────── */}
|
|
970
613
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
971
|
-
{activeSubTab === 'overview' && (<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
|
|
614
|
+
{activeSubTab === 'overview' && !isAnalyzing && (<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
|
|
972
615
|
|
|
973
616
|
{/* Hero Overview Card */}
|
|
974
617
|
<react_native_1.View style={bundleStyles.heroCard}>
|
|
@@ -977,42 +620,59 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
977
620
|
<NetworkIcons_1.PackageIcon color={AppColors_1.AppColors.brandPurple} size={24}/>
|
|
978
621
|
</react_native_1.View>
|
|
979
622
|
<react_native_1.View style={{ flex: 1 }}>
|
|
980
|
-
<react_native_1.Text style={bundleStyles.heroTitle}>
|
|
623
|
+
<react_native_1.Text style={bundleStyles.heroTitle}>{t('bundle.heroTitle')}</react_native_1.Text>
|
|
981
624
|
<react_native_1.Text style={bundleStyles.heroSubtitle}>
|
|
982
|
-
|
|
625
|
+
{analysis?.isLive
|
|
626
|
+
? t('bundle.heroSubtitleLive', { scriptUrl: analysis.scriptURL })
|
|
627
|
+
: t('bundle.heroSubtitle')}
|
|
983
628
|
</react_native_1.Text>
|
|
984
629
|
</react_native_1.View>
|
|
985
|
-
<CopyButton_1.default value={() => summary} label=
|
|
630
|
+
<CopyButton_1.default value={() => ({ ...summary, bundle: analysis })} label={t('bundle.bundleOverviewJson')}/>
|
|
986
631
|
</react_native_1.View>
|
|
987
632
|
|
|
988
633
|
{/* 4-Stat Metric Grid */}
|
|
989
634
|
<react_native_1.View style={bundleStyles.metricsGrid}>
|
|
990
635
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
991
|
-
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
992
|
-
<react_native_1.Text style={bundleStyles.metricValue}
|
|
993
|
-
|
|
636
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>{t('bundle.devBundleSize')}</react_native_1.Text>
|
|
637
|
+
<react_native_1.Text style={bundleStyles.metricValue}>
|
|
638
|
+
{t('bundle.mbValue', {
|
|
639
|
+
size: analysis ? analysis.totalDevMb : summary.totalMb,
|
|
640
|
+
})}
|
|
641
|
+
</react_native_1.Text>
|
|
642
|
+
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
643
|
+
{analysis
|
|
644
|
+
? t('bundle.devBundleHint', {
|
|
645
|
+
kb: analysis.totalDevKb,
|
|
646
|
+
modules: analysis.moduleCount,
|
|
647
|
+
})
|
|
648
|
+
: t('bundle.trackedFilesHint', { count: bundleFiles.length })}
|
|
649
|
+
</react_native_1.Text>
|
|
994
650
|
</react_native_1.View>
|
|
995
651
|
|
|
996
652
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
997
|
-
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
998
|
-
<react_native_1.Text style={[bundleStyles.metricValue, { color:
|
|
999
|
-
{summary.images.kb}
|
|
653
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>{t('bundle.imagesMedia')}</react_native_1.Text>
|
|
654
|
+
<react_native_1.Text style={[bundleStyles.metricValue, { color: AppColors_1.AppColors.pink500 }]}>
|
|
655
|
+
{t('bundle.fileSizeKb', { size: summary.images.kb })}
|
|
656
|
+
</react_native_1.Text>
|
|
657
|
+
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
658
|
+
{t('bundle.pctOfTrackedAssets', { pct: summary.images.pct })}
|
|
1000
659
|
</react_native_1.Text>
|
|
1001
|
-
<react_native_1.Text style={bundleStyles.metricHint}>{summary.images.pct}% of package</react_native_1.Text>
|
|
1002
660
|
</react_native_1.View>
|
|
1003
661
|
|
|
1004
662
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
1005
|
-
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
1006
|
-
<react_native_1.Text style={[bundleStyles.metricValue, { color:
|
|
1007
|
-
{summary.ts.kb + summary.js.kb}
|
|
663
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>{t('bundle.tsJsSource')}</react_native_1.Text>
|
|
664
|
+
<react_native_1.Text style={[bundleStyles.metricValue, { color: AppColors_1.AppColors.sky500 }]}>
|
|
665
|
+
{t('bundle.fileSizeKb', { size: summary.ts.kb + summary.js.kb })}
|
|
1008
666
|
</react_native_1.Text>
|
|
1009
667
|
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
1010
|
-
{(
|
|
668
|
+
{t('bundle.pctOfTrackedAssets', {
|
|
669
|
+
pct: (summary.ts.pct + summary.js.pct).toFixed(1),
|
|
670
|
+
})}
|
|
1011
671
|
</react_native_1.Text>
|
|
1012
672
|
</react_native_1.View>
|
|
1013
673
|
|
|
1014
674
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
1015
|
-
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
675
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>{t('bundle.jsEngine')}</react_native_1.Text>
|
|
1016
676
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 5, marginTop: 2 }}>
|
|
1017
677
|
<react_native_1.View style={[
|
|
1018
678
|
bundleStyles.statusIndicator,
|
|
@@ -1022,17 +682,105 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1022
682
|
{isHermes ? 'Hermes' : 'JSC'}
|
|
1023
683
|
</react_native_1.Text>
|
|
1024
684
|
</react_native_1.View>
|
|
1025
|
-
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
685
|
+
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
686
|
+
{isHermes ? t('bundle.bytecodeAot') : t('bundle.standard')}
|
|
687
|
+
</react_native_1.Text>
|
|
1026
688
|
</react_native_1.View>
|
|
1027
689
|
</react_native_1.View>
|
|
1028
690
|
</react_native_1.View>
|
|
1029
691
|
|
|
692
|
+
{/* Development Bundle Split-Up (derived from the real running bundle) */}
|
|
693
|
+
{analysis && (<react_native_1.View style={bundleStyles.sectionCard}>
|
|
694
|
+
<react_native_1.View style={bundleStyles.sectionHeaderRow}>
|
|
695
|
+
<react_native_1.View>
|
|
696
|
+
<react_native_1.Text style={bundleStyles.sectionTitle}>{t('bundle.splitUpTitle')}</react_native_1.Text>
|
|
697
|
+
<react_native_1.Text style={bundleStyles.sectionSub}>
|
|
698
|
+
{t('bundle.splitUpSub', {
|
|
699
|
+
mb: analysis.totalDevMb,
|
|
700
|
+
files: analysis.filesCount,
|
|
701
|
+
packages: analysis.packageCount,
|
|
702
|
+
})}
|
|
703
|
+
</react_native_1.Text>
|
|
704
|
+
</react_native_1.View>
|
|
705
|
+
<CopyButton_1.default value={() => analysis.splitUp} label={t('bundle.splitUpJson')}/>
|
|
706
|
+
</react_native_1.View>
|
|
707
|
+
|
|
708
|
+
{[
|
|
709
|
+
{
|
|
710
|
+
label: t('bundle.splitAppSource'),
|
|
711
|
+
color: AppColors_1.AppColors.sky500,
|
|
712
|
+
...analysis.splitUp.appSource,
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
label: t('bundle.splitNodeModules'),
|
|
716
|
+
color: AppColors_1.AppColors.indigo500,
|
|
717
|
+
...analysis.splitUp.nodeModules,
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
label: t('bundle.splitAssetsMedia'),
|
|
721
|
+
color: AppColors_1.AppColors.pink500,
|
|
722
|
+
...analysis.splitUp.assetsMedia,
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
label: t('bundle.splitMetroOverhead'),
|
|
726
|
+
color: AppColors_1.AppColors.amber500,
|
|
727
|
+
...analysis.splitUp.metroDevOverhead,
|
|
728
|
+
},
|
|
729
|
+
].map((part, idx) => (<react_native_1.View key={idx} style={bundleStyles.catRowCard}>
|
|
730
|
+
<react_native_1.View style={bundleStyles.catRowTop}>
|
|
731
|
+
<react_native_1.Text style={bundleStyles.catRowIcon}>{['📦', '🧩', '🖼️', '⚙️'][idx]}</react_native_1.Text>
|
|
732
|
+
<react_native_1.View style={{ flex: 1 }}>
|
|
733
|
+
<react_native_1.Text style={bundleStyles.catRowTitle}>{part.label}</react_native_1.Text>
|
|
734
|
+
<react_native_1.Text style={bundleStyles.catRowDesc}>
|
|
735
|
+
{t('bundle.splitSize', { kb: part.kb, mb: part.mb })}
|
|
736
|
+
</react_native_1.Text>
|
|
737
|
+
</react_native_1.View>
|
|
738
|
+
<react_native_1.View style={{ alignItems: 'flex-end' }}>
|
|
739
|
+
<react_native_1.Text style={bundleStyles.catRowSize}>{part.pct}%</react_native_1.Text>
|
|
740
|
+
</react_native_1.View>
|
|
741
|
+
</react_native_1.View>
|
|
742
|
+
<react_native_1.View style={bundleStyles.catProgressTrack}>
|
|
743
|
+
<react_native_1.View style={[
|
|
744
|
+
bundleStyles.catProgressBar,
|
|
745
|
+
{ width: `${part.pct}%`, backgroundColor: part.color },
|
|
746
|
+
]}/>
|
|
747
|
+
</react_native_1.View>
|
|
748
|
+
</react_native_1.View>))}
|
|
749
|
+
|
|
750
|
+
{/* Production Binary Footprint */}
|
|
751
|
+
<react_native_1.View style={bundleStyles.totalSummaryCard}>
|
|
752
|
+
<react_native_1.View style={bundleStyles.totalSummaryRow}>
|
|
753
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
754
|
+
<NetworkIcons_1.PackageIcon color={AppColors_1.AppColors.purple} size={16}/>
|
|
755
|
+
<react_native_1.Text style={bundleStyles.totalSummaryLabel}>
|
|
756
|
+
{t('bundle.productionFootprint')}
|
|
757
|
+
</react_native_1.Text>
|
|
758
|
+
</react_native_1.View>
|
|
759
|
+
<react_native_1.Text style={bundleStyles.totalSummaryValue}>
|
|
760
|
+
{t('bundle.productionValue', {
|
|
761
|
+
ios: analysis.production.ios.totalInstallMb,
|
|
762
|
+
android: analysis.production.android.totalInstallMb,
|
|
763
|
+
})}
|
|
764
|
+
</react_native_1.Text>
|
|
765
|
+
</react_native_1.View>
|
|
766
|
+
<react_native_1.Text style={bundleStyles.totalSummaryFormula}>
|
|
767
|
+
{t('bundle.productionDownload', {
|
|
768
|
+
ios: analysis.production.ios.totalDownloadMb,
|
|
769
|
+
aab: analysis.production.androidAab.totalDownloadMb,
|
|
770
|
+
apk: analysis.production.androidApk.totalDownloadMb,
|
|
771
|
+
})}
|
|
772
|
+
</react_native_1.Text>
|
|
773
|
+
</react_native_1.View>
|
|
774
|
+
</react_native_1.View>)}
|
|
775
|
+
|
|
1030
776
|
{/* Visual Type Distribution Ratio Bar */}
|
|
1031
777
|
<react_native_1.View style={bundleStyles.sectionCard}>
|
|
1032
778
|
<react_native_1.View style={bundleStyles.sectionHeaderRow}>
|
|
1033
779
|
<react_native_1.View>
|
|
1034
|
-
<react_native_1.Text style={bundleStyles.sectionTitle}>
|
|
1035
|
-
<react_native_1.Text style={bundleStyles.sectionSub}>
|
|
780
|
+
<react_native_1.Text style={bundleStyles.sectionTitle}>{t('bundle.treemapTitle')}</react_native_1.Text>
|
|
781
|
+
<react_native_1.Text style={bundleStyles.sectionSub}>
|
|
782
|
+
{t('bundle.treemapSub', { mb: summary.totalMb })}
|
|
783
|
+
</react_native_1.Text>
|
|
1036
784
|
</react_native_1.View>
|
|
1037
785
|
<CopyButton_1.default value={() => ({
|
|
1038
786
|
totalMb: summary.totalMb,
|
|
@@ -1042,48 +790,63 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1042
790
|
js: summary.js,
|
|
1043
791
|
fonts: summary.fonts,
|
|
1044
792
|
json: summary.json,
|
|
1045
|
-
})} label=
|
|
793
|
+
})} label={t('bundle.treemapJson')}/>
|
|
1046
794
|
</react_native_1.View>
|
|
1047
795
|
|
|
1048
796
|
{/* Stacked Colored Bar */}
|
|
1049
797
|
<react_native_1.View style={bundleStyles.treemapBar}>
|
|
1050
|
-
<react_native_1.View style={{ flex: summary.images.pct, backgroundColor:
|
|
1051
|
-
<react_native_1.View style={{ flex: summary.ts.pct, backgroundColor:
|
|
1052
|
-
<react_native_1.View style={{ flex: summary.js.pct, backgroundColor:
|
|
1053
|
-
<react_native_1.View style={{ flex: summary.fonts.pct, backgroundColor:
|
|
1054
|
-
<react_native_1.View style={{ flex: summary.json.pct, backgroundColor:
|
|
798
|
+
<react_native_1.View style={{ flex: summary.images.pct, backgroundColor: AppColors_1.AppColors.pink500, height: 16 }}/>
|
|
799
|
+
<react_native_1.View style={{ flex: summary.ts.pct, backgroundColor: AppColors_1.AppColors.sky500, height: 16 }}/>
|
|
800
|
+
<react_native_1.View style={{ flex: summary.js.pct, backgroundColor: AppColors_1.AppColors.indigo500, height: 16 }}/>
|
|
801
|
+
<react_native_1.View style={{ flex: summary.fonts.pct, backgroundColor: AppColors_1.AppColors.purple500, height: 16 }}/>
|
|
802
|
+
<react_native_1.View style={{ flex: summary.json.pct, backgroundColor: AppColors_1.AppColors.emerald500, height: 16 }}/>
|
|
1055
803
|
</react_native_1.View>
|
|
1056
804
|
|
|
1057
805
|
{/* Legend Grid */}
|
|
1058
806
|
<react_native_1.View style={bundleStyles.legendGrid}>
|
|
1059
807
|
<react_native_1.View style={bundleStyles.legendItem}>
|
|
1060
|
-
<react_native_1.View style={[bundleStyles.legendDot, { backgroundColor:
|
|
808
|
+
<react_native_1.View style={[bundleStyles.legendDot, { backgroundColor: AppColors_1.AppColors.pink500 }]}/>
|
|
1061
809
|
<react_native_1.Text style={bundleStyles.legendText}>
|
|
1062
|
-
|
|
810
|
+
{t('bundle.legendImages')}{' '}
|
|
811
|
+
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
812
|
+
{t('bundle.legendValue', { kb: summary.images.kb, pct: summary.images.pct })}
|
|
813
|
+
</react_native_1.Text>
|
|
1063
814
|
</react_native_1.Text>
|
|
1064
815
|
</react_native_1.View>
|
|
1065
816
|
<react_native_1.View style={bundleStyles.legendItem}>
|
|
1066
|
-
<react_native_1.View style={[bundleStyles.legendDot, { backgroundColor:
|
|
817
|
+
<react_native_1.View style={[bundleStyles.legendDot, { backgroundColor: AppColors_1.AppColors.sky500 }]}/>
|
|
1067
818
|
<react_native_1.Text style={bundleStyles.legendText}>
|
|
1068
|
-
|
|
819
|
+
{t('bundle.legendTs')}{' '}
|
|
820
|
+
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
821
|
+
{t('bundle.legendValue', { kb: summary.ts.kb, pct: summary.ts.pct })}
|
|
822
|
+
</react_native_1.Text>
|
|
1069
823
|
</react_native_1.Text>
|
|
1070
824
|
</react_native_1.View>
|
|
1071
825
|
<react_native_1.View style={bundleStyles.legendItem}>
|
|
1072
|
-
<react_native_1.View style={[bundleStyles.legendDot, { backgroundColor:
|
|
826
|
+
<react_native_1.View style={[bundleStyles.legendDot, { backgroundColor: AppColors_1.AppColors.indigo500 }]}/>
|
|
1073
827
|
<react_native_1.Text style={bundleStyles.legendText}>
|
|
1074
|
-
|
|
828
|
+
{t('bundle.legendJs')}{' '}
|
|
829
|
+
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
830
|
+
{t('bundle.legendValue', { kb: summary.js.kb, pct: summary.js.pct })}
|
|
831
|
+
</react_native_1.Text>
|
|
1075
832
|
</react_native_1.Text>
|
|
1076
833
|
</react_native_1.View>
|
|
1077
834
|
<react_native_1.View style={bundleStyles.legendItem}>
|
|
1078
|
-
<react_native_1.View style={[bundleStyles.legendDot, { backgroundColor:
|
|
835
|
+
<react_native_1.View style={[bundleStyles.legendDot, { backgroundColor: AppColors_1.AppColors.purple500 }]}/>
|
|
1079
836
|
<react_native_1.Text style={bundleStyles.legendText}>
|
|
1080
|
-
|
|
837
|
+
{t('bundle.legendFonts')}{' '}
|
|
838
|
+
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
839
|
+
{t('bundle.legendValue', { kb: summary.fonts.kb, pct: summary.fonts.pct })}
|
|
840
|
+
</react_native_1.Text>
|
|
1081
841
|
</react_native_1.Text>
|
|
1082
842
|
</react_native_1.View>
|
|
1083
843
|
<react_native_1.View style={bundleStyles.legendItem}>
|
|
1084
|
-
<react_native_1.View style={[bundleStyles.legendDot, { backgroundColor:
|
|
844
|
+
<react_native_1.View style={[bundleStyles.legendDot, { backgroundColor: AppColors_1.AppColors.emerald500 }]}/>
|
|
1085
845
|
<react_native_1.Text style={bundleStyles.legendText}>
|
|
1086
|
-
|
|
846
|
+
{t('bundle.legendJson')}{' '}
|
|
847
|
+
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
848
|
+
{t('bundle.legendValue', { kb: summary.json.kb, pct: summary.json.pct })}
|
|
849
|
+
</react_native_1.Text>
|
|
1087
850
|
</react_native_1.Text>
|
|
1088
851
|
</react_native_1.View>
|
|
1089
852
|
</react_native_1.View>
|
|
@@ -1092,7 +855,7 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1092
855
|
{/* Detailed Category Footprint Cards */}
|
|
1093
856
|
<react_native_1.View style={bundleStyles.sectionCard}>
|
|
1094
857
|
<react_native_1.View style={bundleStyles.sectionHeaderRow}>
|
|
1095
|
-
<react_native_1.Text style={bundleStyles.sectionTitle}>
|
|
858
|
+
<react_native_1.Text style={bundleStyles.sectionTitle}>{t('bundle.categoryBreakdown')}</react_native_1.Text>
|
|
1096
859
|
<CopyButton_1.default value={() => ({
|
|
1097
860
|
totalAssets: summary.totalCount,
|
|
1098
861
|
totalSizeKb: summary.totalKb,
|
|
@@ -1103,61 +866,66 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1103
866
|
typescript: summary.ts,
|
|
1104
867
|
json: summary.json,
|
|
1105
868
|
},
|
|
1106
|
-
})} label=
|
|
869
|
+
})} label={t('bundle.categoriesJson')}/>
|
|
1107
870
|
</react_native_1.View>
|
|
1108
871
|
|
|
1109
872
|
{[
|
|
1110
873
|
{
|
|
1111
874
|
icon: '🖼️',
|
|
1112
|
-
title: '
|
|
875
|
+
title: t('bundle.catImagesTitle'),
|
|
1113
876
|
count: summary.images.count,
|
|
1114
|
-
size:
|
|
877
|
+
size: t('bundle.fileSizeKb', { size: summary.images.kb }),
|
|
1115
878
|
pct: summary.images.pct,
|
|
1116
|
-
color:
|
|
1117
|
-
desc: '
|
|
879
|
+
color: AppColors_1.AppColors.pink500,
|
|
880
|
+
desc: t('bundle.catImagesDesc'),
|
|
1118
881
|
},
|
|
1119
882
|
{
|
|
1120
883
|
icon: '⚙️',
|
|
1121
|
-
title: '
|
|
884
|
+
title: t('bundle.catJsTitle'),
|
|
1122
885
|
count: summary.js.count,
|
|
1123
|
-
size:
|
|
886
|
+
size: t('bundle.fileSizeKb', { size: summary.js.kb }),
|
|
1124
887
|
pct: summary.js.pct,
|
|
1125
|
-
color:
|
|
1126
|
-
desc: '
|
|
888
|
+
color: AppColors_1.AppColors.indigo500,
|
|
889
|
+
desc: t('bundle.catJsDesc'),
|
|
1127
890
|
},
|
|
1128
891
|
{
|
|
1129
892
|
icon: '🔤',
|
|
1130
|
-
title: '
|
|
893
|
+
title: t('bundle.catFontsTitle'),
|
|
1131
894
|
count: summary.fonts.count,
|
|
1132
|
-
size:
|
|
895
|
+
size: t('bundle.fileSizeKb', { size: summary.fonts.kb }),
|
|
1133
896
|
pct: summary.fonts.pct,
|
|
1134
|
-
color:
|
|
1135
|
-
desc:
|
|
897
|
+
color: AppColors_1.AppColors.purple500,
|
|
898
|
+
desc: bundleFiles
|
|
899
|
+
.filter(f => f.category === 'font')
|
|
900
|
+
.map(f => f.name)
|
|
901
|
+
.join(', ') || t('bundle.catFontsDesc'),
|
|
1136
902
|
},
|
|
1137
903
|
{
|
|
1138
904
|
icon: '📜',
|
|
1139
|
-
title: '
|
|
905
|
+
title: t('bundle.catTsTitle'),
|
|
1140
906
|
count: summary.ts.count,
|
|
1141
|
-
size:
|
|
907
|
+
size: t('bundle.fileSizeKb', { size: summary.ts.kb }),
|
|
1142
908
|
pct: summary.ts.pct,
|
|
1143
|
-
color:
|
|
1144
|
-
desc: '
|
|
909
|
+
color: AppColors_1.AppColors.sky500,
|
|
910
|
+
desc: t('bundle.catTsDesc'),
|
|
1145
911
|
},
|
|
1146
912
|
{
|
|
1147
913
|
icon: '📄',
|
|
1148
|
-
title: '
|
|
914
|
+
title: t('bundle.catJsonTitle'),
|
|
1149
915
|
count: summary.json.count,
|
|
1150
|
-
size:
|
|
916
|
+
size: t('bundle.fileSizeKb', { size: summary.json.kb }),
|
|
1151
917
|
pct: summary.json.pct,
|
|
1152
|
-
color:
|
|
1153
|
-
desc: '
|
|
918
|
+
color: AppColors_1.AppColors.emerald500,
|
|
919
|
+
desc: t('bundle.catJsonDesc'),
|
|
1154
920
|
},
|
|
1155
921
|
].map((cat, cIdx) => (<react_native_1.View key={cIdx} style={bundleStyles.catRowCard}>
|
|
1156
922
|
<react_native_1.View style={bundleStyles.catRowTop}>
|
|
1157
923
|
<react_native_1.Text style={bundleStyles.catRowIcon}>{cat.icon}</react_native_1.Text>
|
|
1158
924
|
<react_native_1.View style={{ flex: 1 }}>
|
|
1159
925
|
<react_native_1.Text style={bundleStyles.catRowTitle}>{cat.title}</react_native_1.Text>
|
|
1160
|
-
<react_native_1.Text style={bundleStyles.catRowDesc}>
|
|
926
|
+
<react_native_1.Text style={bundleStyles.catRowDesc}>
|
|
927
|
+
{t('bundle.catRowSub', { count: cat.count, desc: cat.desc })}
|
|
928
|
+
</react_native_1.Text>
|
|
1161
929
|
</react_native_1.View>
|
|
1162
930
|
<react_native_1.View style={{ alignItems: 'flex-end' }}>
|
|
1163
931
|
<react_native_1.Text style={bundleStyles.catRowSize}>{cat.size}</react_native_1.Text>
|
|
@@ -1177,14 +945,24 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1177
945
|
<react_native_1.View style={bundleStyles.totalSummaryRow}>
|
|
1178
946
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1179
947
|
<NetworkIcons_1.PackageIcon color={AppColors_1.AppColors.purple} size={16}/>
|
|
1180
|
-
<react_native_1.Text style={bundleStyles.totalSummaryLabel}>
|
|
948
|
+
<react_native_1.Text style={bundleStyles.totalSummaryLabel}>
|
|
949
|
+
{t('bundle.totalBundleAssets')}
|
|
950
|
+
</react_native_1.Text>
|
|
1181
951
|
</react_native_1.View>
|
|
1182
952
|
<react_native_1.Text style={bundleStyles.totalSummaryValue}>
|
|
1183
|
-
{summary.totalKb
|
|
953
|
+
{t('bundle.totalBundleValue', { kb: summary.totalKb, mb: summary.totalMb })}
|
|
1184
954
|
</react_native_1.Text>
|
|
1185
955
|
</react_native_1.View>
|
|
1186
956
|
<react_native_1.Text style={bundleStyles.totalSummaryFormula}>
|
|
1187
|
-
|
|
957
|
+
{t('bundle.totalFormula', {
|
|
958
|
+
images: summary.images.kb,
|
|
959
|
+
js: summary.js.kb,
|
|
960
|
+
fonts: summary.fonts.kb,
|
|
961
|
+
ts: summary.ts.kb,
|
|
962
|
+
json: summary.json.kb,
|
|
963
|
+
total: summary.totalKb,
|
|
964
|
+
count: summary.totalCount,
|
|
965
|
+
})}
|
|
1188
966
|
</react_native_1.Text>
|
|
1189
967
|
</react_native_1.View>
|
|
1190
968
|
</react_native_1.View>
|
|
@@ -1193,16 +971,16 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1193
971
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1194
972
|
{/* ── 2. TAB: FILES BREAKDOWN ─────────────────────────────────────────── */}
|
|
1195
973
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1196
|
-
{activeSubTab === 'files' && (<react_native_1.View style={{ flex: 1 }}>
|
|
974
|
+
{activeSubTab === 'files' && !isAnalyzing && (<react_native_1.View style={{ flex: 1 }}>
|
|
1197
975
|
{/* Search & Category Filter */}
|
|
1198
976
|
<react_native_1.View style={bundleStyles.filterContainer}>
|
|
1199
977
|
<react_native_1.View style={bundleStyles.searchRow}>
|
|
1200
978
|
<NetworkIcons_1.SearchIcon color={AppColors_1.AppColors.grayTextWeak} size={15}/>
|
|
1201
|
-
<react_native_1.TextInput placeholder=
|
|
979
|
+
<react_native_1.TextInput placeholder={t('bundle.searchFilesPlaceholder')} placeholderTextColor={AppColors_1.AppColors.grayTextWeak} value={search} onChangeText={setSearch} style={bundleStyles.searchInput} autoCorrect={false} autoCapitalize="none"/>
|
|
1202
980
|
{search.length > 0 && (<react_native_1.Pressable onPress={() => setSearch('')} hitSlop={10}>
|
|
1203
981
|
<NetworkIcons_1.ClearIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
|
|
1204
982
|
</react_native_1.Pressable>)}
|
|
1205
|
-
<CopyButton_1.default value={() => filteredFiles} label=
|
|
983
|
+
<CopyButton_1.default value={() => filteredFiles} label={t('bundle.filteredFilesJson')}/>
|
|
1206
984
|
</react_native_1.View>
|
|
1207
985
|
|
|
1208
986
|
{/* Category Filter Chips */}
|
|
@@ -1210,24 +988,24 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1210
988
|
{CATEGORY_TABS.map(tab => {
|
|
1211
989
|
const isActive = activeCategory === tab.key;
|
|
1212
990
|
const count = tab.key === 'ALL'
|
|
1213
|
-
?
|
|
991
|
+
? bundleFiles.length
|
|
1214
992
|
: tab.key === 'UNUSED'
|
|
1215
|
-
?
|
|
993
|
+
? bundleFiles.filter(f => f.isConsumed === false).length
|
|
1216
994
|
: tab.key === 'CONSUMED'
|
|
1217
|
-
?
|
|
1218
|
-
:
|
|
995
|
+
? bundleFiles.filter(f => f.isConsumed !== false).length
|
|
996
|
+
: bundleFiles.filter(f => f.category === tab.key).length;
|
|
1219
997
|
return (<TouchableScale_1.default key={tab.key} onPress={() => setActiveCategory(tab.key)} style={[
|
|
1220
998
|
bundleStyles.catPill,
|
|
1221
999
|
isActive && bundleStyles.catPillActive,
|
|
1222
|
-
tab.key === 'UNUSED' && isActive && { backgroundColor:
|
|
1223
|
-
tab.key === 'CONSUMED' && isActive && { backgroundColor:
|
|
1000
|
+
tab.key === 'UNUSED' && isActive && { backgroundColor: AppColors_1.AppColors.red500, borderColor: AppColors_1.AppColors.red600 },
|
|
1001
|
+
tab.key === 'CONSUMED' && isActive && { backgroundColor: AppColors_1.AppColors.emerald600, borderColor: AppColors_1.AppColors.emerald700 },
|
|
1224
1002
|
]}>
|
|
1225
1003
|
<react_native_1.Text style={bundleStyles.catPillIcon}>{tab.icon}</react_native_1.Text>
|
|
1226
1004
|
<react_native_1.Text style={[
|
|
1227
1005
|
bundleStyles.catPillText,
|
|
1228
1006
|
isActive && bundleStyles.catPillTextActive,
|
|
1229
1007
|
]}>
|
|
1230
|
-
{tab.
|
|
1008
|
+
{t(tab.labelKey)} ({count})
|
|
1231
1009
|
</react_native_1.Text>
|
|
1232
1010
|
</TouchableScale_1.default>);
|
|
1233
1011
|
})}
|
|
@@ -1248,7 +1026,7 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1248
1026
|
bundleStyles.viewModeBtnText,
|
|
1249
1027
|
filesViewMode === 'tree' && bundleStyles.viewModeBtnTextActive,
|
|
1250
1028
|
]}>
|
|
1251
|
-
|
|
1029
|
+
{t('bundle.treeView')}
|
|
1252
1030
|
</react_native_1.Text>
|
|
1253
1031
|
</TouchableScale_1.default>
|
|
1254
1032
|
<TouchableScale_1.default onPress={() => setFilesViewMode('list')} style={[
|
|
@@ -1259,21 +1037,24 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1259
1037
|
bundleStyles.viewModeBtnText,
|
|
1260
1038
|
filesViewMode === 'list' && bundleStyles.viewModeBtnTextActive,
|
|
1261
1039
|
]}>
|
|
1262
|
-
|
|
1040
|
+
{t('bundle.flatList')}
|
|
1263
1041
|
</react_native_1.Text>
|
|
1264
1042
|
</TouchableScale_1.default>
|
|
1265
1043
|
</react_native_1.View>
|
|
1266
1044
|
|
|
1267
1045
|
{filesViewMode === 'tree' ? (<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
1268
1046
|
<TouchableScale_1.default onPress={expandAllFolders}>
|
|
1269
|
-
<react_native_1.Text style={bundleStyles.treeActionLink}>
|
|
1047
|
+
<react_native_1.Text style={bundleStyles.treeActionLink}>{t('bundle.expand')}</react_native_1.Text>
|
|
1270
1048
|
</TouchableScale_1.default>
|
|
1271
1049
|
<react_native_1.Text style={{ color: AppColors_1.AppColors.grayTextWeak, fontSize: 11 }}>•</react_native_1.Text>
|
|
1272
1050
|
<TouchableScale_1.default onPress={collapseAllFolders}>
|
|
1273
|
-
<react_native_1.Text style={bundleStyles.treeActionLink}>
|
|
1051
|
+
<react_native_1.Text style={bundleStyles.treeActionLink}>{t('bundle.collapse')}</react_native_1.Text>
|
|
1274
1052
|
</TouchableScale_1.default>
|
|
1275
1053
|
</react_native_1.View>) : (<react_native_1.Text style={bundleStyles.listHeaderCount}>
|
|
1276
|
-
|
|
1054
|
+
{t('bundle.showingFilesOf', {
|
|
1055
|
+
shown: filteredFiles.length,
|
|
1056
|
+
total: bundleFiles.length,
|
|
1057
|
+
})}
|
|
1277
1058
|
</react_native_1.Text>)}
|
|
1278
1059
|
</react_native_1.View>
|
|
1279
1060
|
|
|
@@ -1298,9 +1079,9 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1298
1079
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
|
|
1299
1080
|
<HighlightText_1.default text={file.name} search={search} style={bundleStyles.fileName} highlightStyle={bundleStyles.searchHighlight}/>
|
|
1300
1081
|
{isUnused ? (<react_native_1.View style={bundleStyles.unusedBadge}>
|
|
1301
|
-
<react_native_1.Text style={bundleStyles.unusedBadgeText}
|
|
1082
|
+
<react_native_1.Text style={bundleStyles.unusedBadgeText}>{t('bundle.notConsumed')}</react_native_1.Text>
|
|
1302
1083
|
</react_native_1.View>) : (<react_native_1.View style={bundleStyles.consumedBadge}>
|
|
1303
|
-
<react_native_1.Text style={bundleStyles.consumedBadgeText}
|
|
1084
|
+
<react_native_1.Text style={bundleStyles.consumedBadgeText}>{t('bundle.consumed')}</react_native_1.Text>
|
|
1304
1085
|
</react_native_1.View>)}
|
|
1305
1086
|
</react_native_1.View>
|
|
1306
1087
|
<HighlightText_1.default text={file.path} search={search} style={bundleStyles.filePath} highlightStyle={bundleStyles.searchHighlight} numberOfLines={1}/>
|
|
@@ -1308,14 +1089,14 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1308
1089
|
|
|
1309
1090
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1310
1091
|
<react_native_1.View style={bundleStyles.fileSizeBox}>
|
|
1311
|
-
<react_native_1.Text style={[bundleStyles.fileSizeKb, isUnused && { color:
|
|
1092
|
+
<react_native_1.Text style={[bundleStyles.fileSizeKb, isUnused && { color: AppColors_1.AppColors.amber800Warm }]}>
|
|
1312
1093
|
{file.sizeKb >= 1024
|
|
1313
|
-
?
|
|
1314
|
-
:
|
|
1094
|
+
? t('bundle.fileSizeMb', { size: (file.sizeKb / 1024).toFixed(2) })
|
|
1095
|
+
: t('bundle.fileSizeKb', { size: file.sizeKb })}
|
|
1315
1096
|
</react_native_1.Text>
|
|
1316
1097
|
<react_native_1.Text style={bundleStyles.filePercent}>{pctOfTotal}%</react_native_1.Text>
|
|
1317
1098
|
</react_native_1.View>
|
|
1318
|
-
<CopyButton_1.default value={() => file} label=
|
|
1099
|
+
<CopyButton_1.default value={() => file} label={t('bundle.fileDetailsJson')}/>
|
|
1319
1100
|
</react_native_1.View>
|
|
1320
1101
|
</react_native_1.View>
|
|
1321
1102
|
|
|
@@ -1324,7 +1105,7 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1324
1105
|
bundleStyles.fileProgressBar,
|
|
1325
1106
|
{
|
|
1326
1107
|
width: `${Math.min(100, Math.max(4, Number(pctOfTotal) * 4))}%`,
|
|
1327
|
-
backgroundColor: isUnused ?
|
|
1108
|
+
backgroundColor: isUnused ? AppColors_1.AppColors.red500 : categoryMeta.color,
|
|
1328
1109
|
},
|
|
1329
1110
|
]}/>
|
|
1330
1111
|
</react_native_1.View>
|
|
@@ -1339,9 +1120,9 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1339
1120
|
]}>
|
|
1340
1121
|
<react_native_1.Text style={[
|
|
1341
1122
|
bundleStyles.adviceText,
|
|
1342
|
-
file.status === 'warning' && { color:
|
|
1343
|
-
file.status === 'optimal' && { color:
|
|
1344
|
-
isUnused && { color:
|
|
1123
|
+
file.status === 'warning' && { color: AppColors_1.AppColors.amber800Warm },
|
|
1124
|
+
file.status === 'optimal' && { color: AppColors_1.AppColors.emerald700 },
|
|
1125
|
+
isUnused && { color: AppColors_1.AppColors.red600 },
|
|
1345
1126
|
]}>
|
|
1346
1127
|
{isUnused ? '🗑️ ' : file.status === 'warning' ? '💡 ' : '✨ '}
|
|
1347
1128
|
{file.advice}
|
|
@@ -1357,11 +1138,17 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1357
1138
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1358
1139
|
<NetworkIcons_1.LayersIcon color={AppColors_1.AppColors.purple} size={14}/>
|
|
1359
1140
|
<react_native_1.Text style={bundleStyles.footerTitle}>
|
|
1360
|
-
{
|
|
1141
|
+
{t('bundle.filesOf', {
|
|
1142
|
+
count: filteredFiles.length,
|
|
1143
|
+
total: summary.totalCount,
|
|
1144
|
+
})}
|
|
1361
1145
|
</react_native_1.Text>
|
|
1362
1146
|
</react_native_1.View>
|
|
1363
1147
|
<react_native_1.Text style={bundleStyles.footerSizeVal}>
|
|
1364
|
-
{
|
|
1148
|
+
{t('bundle.kbMbValue', {
|
|
1149
|
+
kb: filteredTotalKb,
|
|
1150
|
+
mb: (filteredTotalKb / 1024).toFixed(2),
|
|
1151
|
+
})}
|
|
1365
1152
|
</react_native_1.Text>
|
|
1366
1153
|
</react_native_1.View>
|
|
1367
1154
|
</react_native_1.View>)}
|
|
@@ -1369,28 +1156,29 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1369
1156
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1370
1157
|
{/* ── 3. TAB: PACKAGES & NODE_MODULES ─────────────────────────────────── */}
|
|
1371
1158
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1372
|
-
{activeSubTab === 'packages' && (<react_native_1.View style={{ flex: 1 }}>
|
|
1159
|
+
{activeSubTab === 'packages' && !isAnalyzing && (<react_native_1.View style={{ flex: 1 }}>
|
|
1373
1160
|
<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
|
|
1374
1161
|
|
|
1375
1162
|
<react_native_1.View style={bundleStyles.filterContainer}>
|
|
1376
1163
|
<react_native_1.View style={bundleStyles.searchRow}>
|
|
1377
1164
|
<NetworkIcons_1.SearchIcon color={AppColors_1.AppColors.grayTextWeak} size={15}/>
|
|
1378
|
-
<react_native_1.TextInput placeholder=
|
|
1165
|
+
<react_native_1.TextInput placeholder={t('bundle.searchPackagesPlaceholder')} placeholderTextColor={AppColors_1.AppColors.grayTextWeak} value={search} onChangeText={setSearch} style={bundleStyles.searchInput} autoCorrect={false} autoCapitalize="none"/>
|
|
1379
1166
|
{search.length > 0 && (<react_native_1.Pressable onPress={() => setSearch('')} hitSlop={10}>
|
|
1380
1167
|
<NetworkIcons_1.ClearIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
|
|
1381
1168
|
</react_native_1.Pressable>)}
|
|
1382
|
-
<CopyButton_1.default value={() => filteredPackages} label=
|
|
1169
|
+
<CopyButton_1.default value={() => filteredPackages} label={t('bundle.dependenciesJson')}/>
|
|
1383
1170
|
</react_native_1.View>
|
|
1384
1171
|
</react_native_1.View>
|
|
1385
1172
|
|
|
1386
1173
|
<react_native_1.Text style={bundleStyles.listHeaderCount}>
|
|
1387
|
-
|
|
1174
|
+
{t('bundle.showingDependencies', { count: filteredPackages.length })}
|
|
1388
1175
|
</react_native_1.Text>
|
|
1389
1176
|
|
|
1390
1177
|
{filteredPackages.map((pkg, index) => {
|
|
1391
|
-
const cleanInstalledVersion = pkg.version.replace(/^\^/, '');
|
|
1392
|
-
const hasUpdate = pkg.latestVersion &&
|
|
1393
|
-
|
|
1178
|
+
const cleanInstalledVersion = pkg.version ? pkg.version.replace(/^\^/, '') : '';
|
|
1179
|
+
const hasUpdate = !!pkg.latestVersion && !!cleanInstalledVersion &&
|
|
1180
|
+
pkg.latestVersion !== cleanInstalledVersion;
|
|
1181
|
+
return (<react_native_1.View key={pkg.id} style={[bundleStyles.fileCard, pkg.isDeprecated && { borderColor: AppColors_1.AppColors.errorBorder, backgroundColor: '#FFFDFD' }]}>
|
|
1394
1182
|
{/* Header Row: #s.no + Logo + Package Name + Version Pill + Update/Deprecated Badges + Size & Copy */}
|
|
1395
1183
|
<react_native_1.View style={bundleStyles.fileCardTop}>
|
|
1396
1184
|
<react_native_1.View style={bundleStyles.sNoBadge}>
|
|
@@ -1404,26 +1192,40 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1404
1192
|
<HighlightText_1.default text={pkg.name} search={search} style={bundleStyles.fileName} highlightStyle={bundleStyles.searchHighlight}/>
|
|
1405
1193
|
<react_native_1.View style={bundleStyles.versionPill}>
|
|
1406
1194
|
<react_native_1.Text style={bundleStyles.versionPillText}>
|
|
1407
|
-
|
|
1195
|
+
{cleanInstalledVersion
|
|
1196
|
+
? t('bundle.versionPrefix', { version: cleanInstalledVersion })
|
|
1197
|
+
: t('bundle.bundled')}
|
|
1408
1198
|
</react_native_1.Text>
|
|
1409
1199
|
</react_native_1.View>
|
|
1410
1200
|
|
|
1411
1201
|
{pkg.isDeprecated ? (<react_native_1.View style={bundleStyles.deprecatedBadge}>
|
|
1412
|
-
<react_native_1.Text style={bundleStyles.deprecatedBadgeText}
|
|
1202
|
+
<react_native_1.Text style={bundleStyles.deprecatedBadgeText}>
|
|
1203
|
+
{t('bundle.deprecated')}
|
|
1204
|
+
</react_native_1.Text>
|
|
1413
1205
|
</react_native_1.View>) : hasUpdate ? (<react_native_1.View style={bundleStyles.updateBadge}>
|
|
1414
|
-
<react_native_1.Text style={bundleStyles.updateBadgeText}
|
|
1415
|
-
|
|
1416
|
-
|
|
1206
|
+
<react_native_1.Text style={bundleStyles.updateBadgeText}>
|
|
1207
|
+
{t('bundle.updateAvailable', { version: pkg.latestVersion })}
|
|
1208
|
+
</react_native_1.Text>
|
|
1209
|
+
</react_native_1.View>) : cleanInstalledVersion ? (<react_native_1.View style={[bundleStyles.updateBadge, { backgroundColor: AppColors_1.AppColors.gray100, borderColor: AppColors_1.AppColors.gray200 }]}>
|
|
1210
|
+
<react_native_1.Text style={[bundleStyles.updateBadgeText, { color: AppColors_1.AppColors.gray600 }]}>
|
|
1211
|
+
{t('bundle.upToDate')}
|
|
1212
|
+
</react_native_1.Text>
|
|
1213
|
+
</react_native_1.View>) : (<react_native_1.View style={[bundleStyles.updateBadge, { backgroundColor: AppColors_1.AppColors.gray100, borderColor: AppColors_1.AppColors.gray200 }]}>
|
|
1214
|
+
<react_native_1.Text style={[bundleStyles.updateBadgeText, { color: AppColors_1.AppColors.gray600 }]}>
|
|
1215
|
+
{t('bundle.bundledBadge')}
|
|
1216
|
+
</react_native_1.Text>
|
|
1417
1217
|
</react_native_1.View>)}
|
|
1418
1218
|
</react_native_1.View>
|
|
1419
1219
|
</react_native_1.View>
|
|
1420
1220
|
|
|
1421
1221
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1422
1222
|
<react_native_1.View style={bundleStyles.fileSizeBox}>
|
|
1423
|
-
<react_native_1.Text style={bundleStyles.fileSizeKb}>
|
|
1223
|
+
<react_native_1.Text style={bundleStyles.fileSizeKb}>
|
|
1224
|
+
{t('bundle.fileSizeKb', { size: pkg.sizeKb })}
|
|
1225
|
+
</react_native_1.Text>
|
|
1424
1226
|
<react_native_1.Text style={bundleStyles.filePercent}>{pkg.percentage}%</react_native_1.Text>
|
|
1425
1227
|
</react_native_1.View>
|
|
1426
|
-
<CopyButton_1.default value={() => pkg} label=
|
|
1228
|
+
<CopyButton_1.default value={() => pkg} label={t('bundle.packageDetailsJson')}/>
|
|
1427
1229
|
</react_native_1.View>
|
|
1428
1230
|
</react_native_1.View>
|
|
1429
1231
|
|
|
@@ -1449,7 +1251,7 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1449
1251
|
<react_native_1.View style={bundleStyles.fileProgressTrack}>
|
|
1450
1252
|
<react_native_1.View style={[
|
|
1451
1253
|
bundleStyles.fileProgressBar,
|
|
1452
|
-
{ width: `${pkg.percentage * 2}%`, backgroundColor: pkg.isDeprecated ?
|
|
1254
|
+
{ width: `${pkg.percentage * 2}%`, backgroundColor: pkg.isDeprecated ? AppColors_1.AppColors.red500 : pkg.color },
|
|
1453
1255
|
]}/>
|
|
1454
1256
|
</react_native_1.View>
|
|
1455
1257
|
|
|
@@ -1458,7 +1260,7 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1458
1260
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
1459
1261
|
<react_native_1.View style={bundleStyles.typeTag}>
|
|
1460
1262
|
<react_native_1.Text style={bundleStyles.typeTagText}>
|
|
1461
|
-
{pkg.type === 'direct' ? '
|
|
1263
|
+
{pkg.type === 'direct' ? t('bundle.direct') : t('bundle.transitive')}
|
|
1462
1264
|
</react_native_1.Text>
|
|
1463
1265
|
</react_native_1.View>
|
|
1464
1266
|
{pkg.lastActive && (<react_native_1.Text style={bundleStyles.lastActiveText}>
|
|
@@ -1468,13 +1270,13 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1468
1270
|
|
|
1469
1271
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
1470
1272
|
<react_native_1.Text style={bundleStyles.fileMetaText}>
|
|
1471
|
-
|
|
1273
|
+
{t('bundle.minified', { size: pkg.sizeKb })}
|
|
1472
1274
|
</react_native_1.Text>
|
|
1473
1275
|
<TouchableScale_1.default onPress={() => {
|
|
1474
1276
|
const url = pkg.npmUrl || `https://www.npmjs.com/package/${pkg.name}`;
|
|
1475
1277
|
react_native_1.Linking.openURL(url).catch(() => { });
|
|
1476
1278
|
}} style={bundleStyles.npmLinkBtn}>
|
|
1477
|
-
<react_native_1.Text style={bundleStyles.npmLinkText}>
|
|
1279
|
+
<react_native_1.Text style={bundleStyles.npmLinkText}>{t('bundle.npmLink')}</react_native_1.Text>
|
|
1478
1280
|
</TouchableScale_1.default>
|
|
1479
1281
|
</react_native_1.View>
|
|
1480
1282
|
</react_native_1.View>
|
|
@@ -1487,11 +1289,14 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1487
1289
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1488
1290
|
<NetworkIcons_1.PackageIcon color={AppColors_1.AppColors.purple} size={14}/>
|
|
1489
1291
|
<react_native_1.Text style={bundleStyles.footerTitle}>
|
|
1490
|
-
{filteredPackages.length}
|
|
1292
|
+
{t('bundle.dependenciesCount', { count: filteredPackages.length })}
|
|
1491
1293
|
</react_native_1.Text>
|
|
1492
1294
|
</react_native_1.View>
|
|
1493
1295
|
<react_native_1.Text style={bundleStyles.footerSizeVal}>
|
|
1494
|
-
{
|
|
1296
|
+
{t('bundle.kbMbValue', {
|
|
1297
|
+
kb: packagesTotalKb,
|
|
1298
|
+
mb: (packagesTotalKb / 1024).toFixed(2),
|
|
1299
|
+
})}
|
|
1495
1300
|
</react_native_1.Text>
|
|
1496
1301
|
</react_native_1.View>
|
|
1497
1302
|
</react_native_1.View>)}
|
|
@@ -1499,24 +1304,32 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1499
1304
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1500
1305
|
{/* ── 4. TAB: MEDIA & ASSET AUDITOR ───────────────────────────────────── */}
|
|
1501
1306
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1502
|
-
{activeSubTab === 'media' && (<react_native_1.View style={{ flex: 1 }}>
|
|
1307
|
+
{activeSubTab === 'media' && !isAnalyzing && (<react_native_1.View style={{ flex: 1 }}>
|
|
1503
1308
|
<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
|
|
1504
1309
|
|
|
1505
1310
|
<react_native_1.View style={bundleStyles.tipsCard}>
|
|
1506
1311
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8 }}>
|
|
1507
1312
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1508
1313
|
<NetworkIcons_1.StorageIcon color={AppColors_1.AppColors.purple} size={18}/>
|
|
1509
|
-
<react_native_1.Text style={bundleStyles.tipsHeading}>
|
|
1314
|
+
<react_native_1.Text style={bundleStyles.tipsHeading}>{t('bundle.mediaAuditorTitle')}</react_native_1.Text>
|
|
1510
1315
|
</react_native_1.View>
|
|
1511
|
-
<CopyButton_1.default value={() => mediaFiles} label=
|
|
1316
|
+
<CopyButton_1.default value={() => mediaFiles} label={t('bundle.mediaAssetsJson')}/>
|
|
1512
1317
|
</react_native_1.View>
|
|
1513
1318
|
<react_native_1.Text style={bundleStyles.tipDesc}>
|
|
1514
|
-
|
|
1319
|
+
{t('bundle.mediaAuditorPrefix')}{' '}
|
|
1320
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interBold, color: AppColors_1.AppColors.purple }}>
|
|
1321
|
+
{summary.images.pct + summary.fonts.pct}%
|
|
1322
|
+
</react_native_1.Text>{' '}
|
|
1323
|
+
{t('bundle.mediaAuditorMid', { kb: summary.images.kb + summary.fonts.kb })}{' '}
|
|
1324
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interBold, color: AppColors_1.AppColors.emerald700 }}>
|
|
1325
|
+
{t('bundle.mediaSavings', { size: 540 })}
|
|
1326
|
+
</react_native_1.Text>{' '}
|
|
1327
|
+
{t('bundle.mediaAuditorSuffix')}
|
|
1515
1328
|
</react_native_1.Text>
|
|
1516
1329
|
</react_native_1.View>
|
|
1517
1330
|
|
|
1518
1331
|
<react_native_1.Text style={bundleStyles.listHeaderCount}>
|
|
1519
|
-
|
|
1332
|
+
{t('bundle.mediaAssetsList', { count: mediaFiles.length })}
|
|
1520
1333
|
</react_native_1.Text>
|
|
1521
1334
|
|
|
1522
1335
|
{mediaFiles.map((file, index) => (<react_native_1.View key={file.id} style={bundleStyles.fileCard}>
|
|
@@ -1534,9 +1347,11 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1534
1347
|
|
|
1535
1348
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1536
1349
|
<react_native_1.View style={bundleStyles.fileSizeBox}>
|
|
1537
|
-
<react_native_1.Text style={bundleStyles.fileSizeKb}>
|
|
1350
|
+
<react_native_1.Text style={bundleStyles.fileSizeKb}>
|
|
1351
|
+
{t('bundle.fileSizeKb', { size: file.sizeKb })}
|
|
1352
|
+
</react_native_1.Text>
|
|
1538
1353
|
</react_native_1.View>
|
|
1539
|
-
<CopyButton_1.default value={() => file} label=
|
|
1354
|
+
<CopyButton_1.default value={() => file} label={t('bundle.mediaItemJson')}/>
|
|
1540
1355
|
</react_native_1.View>
|
|
1541
1356
|
</react_native_1.View>
|
|
1542
1357
|
|
|
@@ -1549,8 +1364,8 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1549
1364
|
]}>
|
|
1550
1365
|
<react_native_1.Text style={[
|
|
1551
1366
|
bundleStyles.adviceText,
|
|
1552
|
-
file.status === 'warning' && { color:
|
|
1553
|
-
file.status === 'optimal' && { color:
|
|
1367
|
+
file.status === 'warning' && { color: AppColors_1.AppColors.amber800Warm },
|
|
1368
|
+
file.status === 'optimal' && { color: AppColors_1.AppColors.emerald700 },
|
|
1554
1369
|
]}>
|
|
1555
1370
|
{file.status === 'warning' ? '💡 ' : '✨ '}
|
|
1556
1371
|
{file.advice}
|
|
@@ -1565,11 +1380,14 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1565
1380
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1566
1381
|
<NetworkIcons_1.StorageIcon color={AppColors_1.AppColors.purple} size={14}/>
|
|
1567
1382
|
<react_native_1.Text style={bundleStyles.footerTitle}>
|
|
1568
|
-
{mediaFiles.length}
|
|
1383
|
+
{t('bundle.mediaAndFonts', { count: mediaFiles.length })}
|
|
1569
1384
|
</react_native_1.Text>
|
|
1570
1385
|
</react_native_1.View>
|
|
1571
1386
|
<react_native_1.Text style={bundleStyles.footerSizeVal}>
|
|
1572
|
-
{
|
|
1387
|
+
{t('bundle.kbMbValue', {
|
|
1388
|
+
kb: mediaTotalKb,
|
|
1389
|
+
mb: (mediaTotalKb / 1024).toFixed(2),
|
|
1390
|
+
})}
|
|
1573
1391
|
</react_native_1.Text>
|
|
1574
1392
|
</react_native_1.View>
|
|
1575
1393
|
</react_native_1.View>)}
|
|
@@ -1583,49 +1401,49 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1583
1401
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
|
|
1584
1402
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1585
1403
|
<NetworkIcons_1.CircleAlertIcon color={AppColors_1.AppColors.purple} size={18}/>
|
|
1586
|
-
<react_native_1.Text style={bundleStyles.tipsHeading}>
|
|
1404
|
+
<react_native_1.Text style={bundleStyles.tipsHeading}>{t('bundle.optimizerTitle')}</react_native_1.Text>
|
|
1587
1405
|
</react_native_1.View>
|
|
1588
1406
|
<CopyButton_1.default value={() => [
|
|
1589
|
-
'
|
|
1590
|
-
|
|
1591
|
-
'
|
|
1592
|
-
'
|
|
1593
|
-
'
|
|
1594
|
-
]} label=
|
|
1407
|
+
t('bundle.optTip1Title'),
|
|
1408
|
+
`${t('bundle.optTip2Title')} (${isHermes ? t('bundle.active') : t('bundle.actionRequired')})`,
|
|
1409
|
+
t('bundle.optTip3Title'),
|
|
1410
|
+
t('bundle.optTip4Title'),
|
|
1411
|
+
t('bundle.optTip5Title'),
|
|
1412
|
+
]} label={t('bundle.optimizationChecklist')}/>
|
|
1595
1413
|
</react_native_1.View>
|
|
1596
1414
|
|
|
1597
1415
|
{[
|
|
1598
1416
|
{
|
|
1599
|
-
title: '
|
|
1600
|
-
desc: '
|
|
1601
|
-
badge: '
|
|
1602
|
-
badgeColor:
|
|
1417
|
+
title: t('bundle.optTip1Title'),
|
|
1418
|
+
desc: t('bundle.optTip1Desc'),
|
|
1419
|
+
badge: t('bundle.highImpact'),
|
|
1420
|
+
badgeColor: AppColors_1.AppColors.pink500,
|
|
1603
1421
|
},
|
|
1604
1422
|
{
|
|
1605
|
-
title: '
|
|
1423
|
+
title: t('bundle.optTip2Title'),
|
|
1606
1424
|
desc: isHermes
|
|
1607
|
-
? '
|
|
1608
|
-
: '
|
|
1609
|
-
badge: isHermes ? '
|
|
1610
|
-
badgeColor: isHermes ?
|
|
1425
|
+
? t('bundle.optTip2DescActive')
|
|
1426
|
+
: t('bundle.optTip2DescInactive'),
|
|
1427
|
+
badge: isHermes ? t('bundle.active') : t('bundle.actionRequired'),
|
|
1428
|
+
badgeColor: isHermes ? AppColors_1.AppColors.emerald500 : AppColors_1.AppColors.amber500,
|
|
1611
1429
|
},
|
|
1612
1430
|
{
|
|
1613
|
-
title: '
|
|
1614
|
-
desc: '
|
|
1615
|
-
badge: '
|
|
1616
|
-
badgeColor:
|
|
1431
|
+
title: t('bundle.optTip3Title'),
|
|
1432
|
+
desc: t('bundle.optTip3Desc'),
|
|
1433
|
+
badge: t('bundle.mediumImpact'),
|
|
1434
|
+
badgeColor: AppColors_1.AppColors.purple500,
|
|
1617
1435
|
},
|
|
1618
1436
|
{
|
|
1619
|
-
title: '
|
|
1620
|
-
desc: '
|
|
1621
|
-
badge: '
|
|
1622
|
-
badgeColor:
|
|
1437
|
+
title: t('bundle.optTip4Title'),
|
|
1438
|
+
desc: t('bundle.optTip4Desc'),
|
|
1439
|
+
badge: t('bundle.bestPractice'),
|
|
1440
|
+
badgeColor: AppColors_1.AppColors.sky500,
|
|
1623
1441
|
},
|
|
1624
1442
|
{
|
|
1625
|
-
title: '
|
|
1626
|
-
desc: '
|
|
1627
|
-
badge: '
|
|
1628
|
-
badgeColor:
|
|
1443
|
+
title: t('bundle.optTip5Title'),
|
|
1444
|
+
desc: t('bundle.optTip5Desc'),
|
|
1445
|
+
badge: t('bundle.bestPractice'),
|
|
1446
|
+
badgeColor: AppColors_1.AppColors.indigo500,
|
|
1629
1447
|
},
|
|
1630
1448
|
].map((tip, tIdx) => (<react_native_1.View key={tIdx} style={bundleStyles.tipItem}>
|
|
1631
1449
|
<react_native_1.View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 2 }}>
|
|
@@ -1641,7 +1459,7 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1641
1459
|
{tip.badge}
|
|
1642
1460
|
</react_native_1.Text>
|
|
1643
1461
|
</react_native_1.View>
|
|
1644
|
-
<CopyButton_1.default value={() => tip} label=
|
|
1462
|
+
<CopyButton_1.default value={() => tip} label={t('bundle.tipDetails')}/>
|
|
1645
1463
|
</react_native_1.View>
|
|
1646
1464
|
</react_native_1.View>
|
|
1647
1465
|
<react_native_1.Text style={bundleStyles.tipDesc}>{tip.desc}</react_native_1.Text>
|
|
@@ -1657,6 +1475,23 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
1657
1475
|
borderBottomWidth: 1,
|
|
1658
1476
|
borderBottomColor: AppColors_1.AppColors.dividerColor,
|
|
1659
1477
|
},
|
|
1478
|
+
analyzingContainer: {
|
|
1479
|
+
flex: 1,
|
|
1480
|
+
alignItems: 'center',
|
|
1481
|
+
justifyContent: 'center',
|
|
1482
|
+
gap: 8,
|
|
1483
|
+
padding: 24,
|
|
1484
|
+
},
|
|
1485
|
+
analyzingText: {
|
|
1486
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1487
|
+
fontSize: 13,
|
|
1488
|
+
color: AppColors_1.AppColors.primaryBlack,
|
|
1489
|
+
},
|
|
1490
|
+
analyzingHint: {
|
|
1491
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
1492
|
+
fontSize: 11,
|
|
1493
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
1494
|
+
},
|
|
1660
1495
|
subTabsScroll: {
|
|
1661
1496
|
paddingHorizontal: 12,
|
|
1662
1497
|
gap: 8,
|
|
@@ -2212,41 +2047,41 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
2212
2047
|
paddingHorizontal: 7,
|
|
2213
2048
|
paddingVertical: 2,
|
|
2214
2049
|
borderRadius: 5,
|
|
2215
|
-
backgroundColor:
|
|
2050
|
+
backgroundColor: AppColors_1.AppColors.npmRedTint,
|
|
2216
2051
|
borderWidth: 1,
|
|
2217
|
-
borderColor:
|
|
2052
|
+
borderColor: AppColors_1.AppColors.npmRedBorder,
|
|
2218
2053
|
},
|
|
2219
2054
|
npmLinkText: {
|
|
2220
2055
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2221
2056
|
fontSize: 9.5,
|
|
2222
|
-
color:
|
|
2057
|
+
color: AppColors_1.AppColors.npmRed,
|
|
2223
2058
|
},
|
|
2224
2059
|
deprecatedBadge: {
|
|
2225
2060
|
paddingHorizontal: 6,
|
|
2226
2061
|
paddingVertical: 1.5,
|
|
2227
2062
|
borderRadius: 4,
|
|
2228
|
-
backgroundColor:
|
|
2063
|
+
backgroundColor: AppColors_1.AppColors.red100,
|
|
2229
2064
|
borderWidth: 1,
|
|
2230
|
-
borderColor:
|
|
2065
|
+
borderColor: AppColors_1.AppColors.errorBorder,
|
|
2231
2066
|
},
|
|
2232
2067
|
deprecatedBadgeText: {
|
|
2233
2068
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2234
2069
|
fontSize: 9,
|
|
2235
|
-
color:
|
|
2070
|
+
color: AppColors_1.AppColors.red600,
|
|
2236
2071
|
letterSpacing: 0.3,
|
|
2237
2072
|
},
|
|
2238
2073
|
updateBadge: {
|
|
2239
2074
|
paddingHorizontal: 6,
|
|
2240
2075
|
paddingVertical: 1.5,
|
|
2241
2076
|
borderRadius: 4,
|
|
2242
|
-
backgroundColor:
|
|
2077
|
+
backgroundColor: AppColors_1.AppColors.green100,
|
|
2243
2078
|
borderWidth: 1,
|
|
2244
|
-
borderColor:
|
|
2079
|
+
borderColor: AppColors_1.AppColors.greenBorder,
|
|
2245
2080
|
},
|
|
2246
2081
|
updateBadgeText: {
|
|
2247
2082
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2248
2083
|
fontSize: 9,
|
|
2249
|
-
color:
|
|
2084
|
+
color: AppColors_1.AppColors.emerald700,
|
|
2250
2085
|
},
|
|
2251
2086
|
lastActiveText: {
|
|
2252
2087
|
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
@@ -2254,45 +2089,45 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
2254
2089
|
color: AppColors_1.AppColors.grayTextWeak,
|
|
2255
2090
|
},
|
|
2256
2091
|
deprecationBox: {
|
|
2257
|
-
backgroundColor:
|
|
2092
|
+
backgroundColor: AppColors_1.AppColors.errorCardBg,
|
|
2258
2093
|
borderRadius: 6,
|
|
2259
2094
|
paddingHorizontal: 8,
|
|
2260
2095
|
paddingVertical: 5,
|
|
2261
2096
|
borderWidth: 1,
|
|
2262
|
-
borderColor:
|
|
2097
|
+
borderColor: AppColors_1.AppColors.errorBorder,
|
|
2263
2098
|
marginTop: 3,
|
|
2264
2099
|
},
|
|
2265
2100
|
deprecationText: {
|
|
2266
2101
|
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
2267
2102
|
fontSize: 10.5,
|
|
2268
|
-
color:
|
|
2103
|
+
color: AppColors_1.AppColors.rose700,
|
|
2269
2104
|
lineHeight: 14,
|
|
2270
2105
|
},
|
|
2271
2106
|
unusedBadge: {
|
|
2272
2107
|
paddingHorizontal: 6,
|
|
2273
2108
|
paddingVertical: 1.5,
|
|
2274
2109
|
borderRadius: 4,
|
|
2275
|
-
backgroundColor:
|
|
2110
|
+
backgroundColor: AppColors_1.AppColors.red100,
|
|
2276
2111
|
borderWidth: 1,
|
|
2277
|
-
borderColor:
|
|
2112
|
+
borderColor: AppColors_1.AppColors.errorBorder,
|
|
2278
2113
|
},
|
|
2279
2114
|
unusedBadgeText: {
|
|
2280
2115
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2281
2116
|
fontSize: 9.5,
|
|
2282
|
-
color:
|
|
2117
|
+
color: AppColors_1.AppColors.red600,
|
|
2283
2118
|
},
|
|
2284
2119
|
consumedBadge: {
|
|
2285
2120
|
paddingHorizontal: 6,
|
|
2286
2121
|
paddingVertical: 1.5,
|
|
2287
2122
|
borderRadius: 4,
|
|
2288
|
-
backgroundColor:
|
|
2123
|
+
backgroundColor: AppColors_1.AppColors.green100,
|
|
2289
2124
|
borderWidth: 1,
|
|
2290
|
-
borderColor:
|
|
2125
|
+
borderColor: AppColors_1.AppColors.greenBorder,
|
|
2291
2126
|
},
|
|
2292
2127
|
consumedBadgeText: {
|
|
2293
2128
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2294
2129
|
fontSize: 9.5,
|
|
2295
|
-
color:
|
|
2130
|
+
color: AppColors_1.AppColors.emerald600,
|
|
2296
2131
|
},
|
|
2297
2132
|
treeFolderChevronWrap: {
|
|
2298
2133
|
width: 18,
|
|
@@ -2303,13 +2138,13 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
2303
2138
|
justifyContent: 'center',
|
|
2304
2139
|
},
|
|
2305
2140
|
treeFileCardUnused: {
|
|
2306
|
-
borderColor:
|
|
2307
|
-
backgroundColor:
|
|
2141
|
+
borderColor: AppColors_1.AppColors.errorBorder,
|
|
2142
|
+
backgroundColor: AppColors_1.AppColors.red50,
|
|
2308
2143
|
},
|
|
2309
2144
|
adviceUnused: {
|
|
2310
|
-
backgroundColor:
|
|
2145
|
+
backgroundColor: AppColors_1.AppColors.errorCardBg,
|
|
2311
2146
|
borderWidth: 1,
|
|
2312
|
-
borderColor:
|
|
2147
|
+
borderColor: AppColors_1.AppColors.errorBorder,
|
|
2313
2148
|
},
|
|
2314
2149
|
adviceBadge: {
|
|
2315
2150
|
paddingHorizontal: 8,
|
|
@@ -2318,14 +2153,14 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
2318
2153
|
marginTop: 2,
|
|
2319
2154
|
},
|
|
2320
2155
|
adviceWarning: {
|
|
2321
|
-
backgroundColor:
|
|
2156
|
+
backgroundColor: AppColors_1.AppColors.amber100,
|
|
2322
2157
|
borderWidth: 1,
|
|
2323
|
-
borderColor:
|
|
2158
|
+
borderColor: AppColors_1.AppColors.amber200,
|
|
2324
2159
|
},
|
|
2325
2160
|
adviceOptimal: {
|
|
2326
|
-
backgroundColor:
|
|
2161
|
+
backgroundColor: AppColors_1.AppColors.green100,
|
|
2327
2162
|
borderWidth: 1,
|
|
2328
|
-
borderColor:
|
|
2163
|
+
borderColor: AppColors_1.AppColors.greenBorder,
|
|
2329
2164
|
},
|
|
2330
2165
|
adviceText: {
|
|
2331
2166
|
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
@@ -2343,21 +2178,21 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
2343
2178
|
fontSize: 9,
|
|
2344
2179
|
},
|
|
2345
2180
|
searchHighlight: {
|
|
2346
|
-
backgroundColor:
|
|
2347
|
-
color:
|
|
2181
|
+
backgroundColor: AppColors_1.AppColors.yellow200,
|
|
2182
|
+
color: AppColors_1.AppColors.yellow800,
|
|
2348
2183
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2349
2184
|
},
|
|
2350
2185
|
tipsCard: {
|
|
2351
|
-
backgroundColor:
|
|
2186
|
+
backgroundColor: AppColors_1.AppColors.purple50,
|
|
2352
2187
|
borderRadius: 14,
|
|
2353
2188
|
padding: 14,
|
|
2354
2189
|
borderWidth: 1,
|
|
2355
|
-
borderColor:
|
|
2190
|
+
borderColor: AppColors_1.AppColors.purple200,
|
|
2356
2191
|
},
|
|
2357
2192
|
tipsHeading: {
|
|
2358
2193
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2359
2194
|
fontSize: 13.5,
|
|
2360
|
-
color:
|
|
2195
|
+
color: AppColors_1.AppColors.purple800,
|
|
2361
2196
|
},
|
|
2362
2197
|
totalSummaryCard: {
|
|
2363
2198
|
marginTop: 10,
|
|
@@ -2421,17 +2256,17 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
2421
2256
|
padding: 10,
|
|
2422
2257
|
borderRadius: 8,
|
|
2423
2258
|
borderWidth: 1,
|
|
2424
|
-
borderColor:
|
|
2259
|
+
borderColor: AppColors_1.AppColors.purple200,
|
|
2425
2260
|
},
|
|
2426
2261
|
tipTitle: {
|
|
2427
2262
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2428
2263
|
fontSize: 12,
|
|
2429
|
-
color:
|
|
2264
|
+
color: AppColors_1.AppColors.purple900,
|
|
2430
2265
|
},
|
|
2431
2266
|
tipDesc: {
|
|
2432
2267
|
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
2433
2268
|
fontSize: 11,
|
|
2434
|
-
color:
|
|
2269
|
+
color: AppColors_1.AppColors.gray500,
|
|
2435
2270
|
lineHeight: 16,
|
|
2436
2271
|
marginTop: 4,
|
|
2437
2272
|
},
|