react-native-inapp-inspector 1.1.34 → 1.1.35
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/ConsoleLogCard.js +57 -56
- package/dist/commonjs/components/CopyButton.js +7 -1
- package/dist/commonjs/components/Inspector/BundleTab.js +19 -19
- package/dist/commonjs/components/Inspector/CrashDetail.js +16 -12
- package/dist/commonjs/components/Inspector/InspectorHeader.js +16 -16
- package/dist/commonjs/components/Inspector/MainScreen.js +6 -2
- package/dist/commonjs/components/Inspector/NetworkTab.js +97 -1
- package/dist/commonjs/components/Inspector/ReduxDetail.js +24 -19
- package/dist/commonjs/components/Inspector/ReduxTab.js +12 -8
- package/dist/commonjs/components/Inspector/SettingsPanel.js +1243 -673
- package/dist/commonjs/components/LogCard.js +27 -9
- package/dist/commonjs/components/MetaAccordion.js +42 -0
- package/dist/commonjs/components/NetworkIcons.d.ts +9 -0
- package/dist/commonjs/components/NetworkIcons.js +48 -1
- package/dist/commonjs/components/Toast.js +3 -3
- package/dist/commonjs/components/TouchableScale.d.ts +4 -2
- package/dist/commonjs/components/TouchableScale.js +4 -4
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/analyticsLogger.d.ts +2 -0
- package/dist/commonjs/customHooks/analyticsLogger.js +10 -1
- package/dist/commonjs/customHooks/bundleAnalyzer.d.ts +2 -0
- package/dist/commonjs/customHooks/bundleAnalyzer.js +26 -17
- package/dist/commonjs/customHooks/consoleLogger.d.ts +2 -0
- package/dist/commonjs/customHooks/consoleLogger.js +10 -1
- package/dist/commonjs/customHooks/crashHandler.d.ts +2 -0
- package/dist/commonjs/customHooks/crashHandler.js +10 -1
- package/dist/commonjs/customHooks/networkLogger.d.ts +2 -0
- package/dist/commonjs/customHooks/networkLogger.js +12 -1
- package/dist/commonjs/customHooks/performanceTracker.d.ts +3 -1
- package/dist/commonjs/customHooks/performanceTracker.js +18 -4
- package/dist/commonjs/customHooks/reduxLogger.d.ts +2 -0
- package/dist/commonjs/customHooks/reduxLogger.js +10 -1
- package/dist/commonjs/i18n/locales/en.json +96 -28
- package/dist/commonjs/index.js +78 -34
- package/dist/commonjs/styles/AppColors.d.ts +28 -0
- package/dist/commonjs/styles/AppColors.js +30 -0
- package/dist/esm/components/ConsoleLogCard.js +58 -57
- package/dist/esm/components/CopyButton.js +7 -1
- package/dist/esm/components/Inspector/BundleTab.js +19 -19
- package/dist/esm/components/Inspector/CrashDetail.js +16 -12
- package/dist/esm/components/Inspector/InspectorHeader.js +16 -16
- package/dist/esm/components/Inspector/MainScreen.js +6 -2
- package/dist/esm/components/Inspector/NetworkTab.js +99 -3
- package/dist/esm/components/Inspector/ReduxDetail.js +24 -19
- package/dist/esm/components/Inspector/ReduxTab.js +12 -8
- package/dist/esm/components/Inspector/SettingsPanel.js +1246 -676
- package/dist/esm/components/LogCard.js +27 -9
- package/dist/esm/components/MetaAccordion.js +42 -0
- package/dist/esm/components/NetworkIcons.d.ts +9 -0
- package/dist/esm/components/NetworkIcons.js +38 -0
- package/dist/esm/components/Toast.js +3 -3
- package/dist/esm/components/TouchableScale.d.ts +4 -2
- package/dist/esm/components/TouchableScale.js +4 -4
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/analyticsLogger.d.ts +2 -0
- package/dist/esm/customHooks/analyticsLogger.js +7 -0
- package/dist/esm/customHooks/bundleAnalyzer.d.ts +2 -0
- package/dist/esm/customHooks/bundleAnalyzer.js +23 -16
- package/dist/esm/customHooks/consoleLogger.d.ts +2 -0
- package/dist/esm/customHooks/consoleLogger.js +7 -0
- package/dist/esm/customHooks/crashHandler.d.ts +2 -0
- package/dist/esm/customHooks/crashHandler.js +7 -0
- package/dist/esm/customHooks/networkLogger.d.ts +2 -0
- package/dist/esm/customHooks/networkLogger.js +9 -0
- package/dist/esm/customHooks/performanceTracker.d.ts +3 -1
- package/dist/esm/customHooks/performanceTracker.js +15 -3
- package/dist/esm/customHooks/reduxLogger.d.ts +2 -0
- package/dist/esm/customHooks/reduxLogger.js +7 -0
- package/dist/esm/i18n/locales/en.json +96 -28
- package/dist/esm/index.js +64 -20
- package/dist/esm/styles/AppColors.d.ts +28 -0
- package/dist/esm/styles/AppColors.js +30 -0
- package/package.json +3 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Alert, Platform, ScrollView,
|
|
1
|
+
import React, { useMemo, useState, useEffect } from 'react';
|
|
2
|
+
import { Alert, Platform, ScrollView, StatusBar, Text, View, } from 'react-native';
|
|
3
3
|
import Svg, { Path } from 'react-native-svg';
|
|
4
4
|
import LinearGradient from 'react-native-linear-gradient';
|
|
5
5
|
import { animateNextLayout, useInspector } from './InspectorContext';
|
|
@@ -12,32 +12,124 @@ import { isPersistentStorageAvailable } from '../../helpers/settingsStore';
|
|
|
12
12
|
import { clearNetworkLogs } from '../../customHooks/networkLogger';
|
|
13
13
|
import { clearConsoleLogs } from '../../customHooks/consoleLogger';
|
|
14
14
|
import { clearAnalyticsEvents } from '../../customHooks/analyticsLogger';
|
|
15
|
-
import { clearCrashRecords
|
|
15
|
+
import { clearCrashRecords } from '../../customHooks/crashHandler';
|
|
16
|
+
import { clearCachedBundleAnalysis } from '../../customHooks/bundleAnalyzer';
|
|
17
|
+
import { clearPerformanceEvents } from '../../customHooks/performanceTracker';
|
|
16
18
|
import { isReduxConnected } from '../../customHooks/reduxLogger';
|
|
17
19
|
import { isAnalyticsConnected } from '../../customHooks/analyticsLogger';
|
|
18
20
|
import { useTranslation } from '../../i18n';
|
|
19
|
-
import { SignalIcon, TerminalIcon, AnalyticsIcon, SettingsIcon, SunIcon, MoonIcon, ScreenIcon, MotionIcon, LayersIcon, EyeIcon, CheckIcon, TrashIcon, WhiteBackNavigation, PackageIcon, ReduxIcon, PerformanceIcon, CrashIcon, ShieldAlertIcon, } from '../NetworkIcons';
|
|
21
|
+
import { SignalIcon, TerminalIcon, AnalyticsIcon, SettingsIcon, SunIcon, MoonIcon, ScreenIcon, MotionIcon, LayersIcon, EyeIcon, CheckIcon, TrashIcon, WhiteBackNavigation, PackageIcon, ReduxIcon, PerformanceIcon, CrashIcon, ShieldAlertIcon, ForwardChevronIcon, } from '../NetworkIcons';
|
|
20
22
|
const SettingsPanel = () => {
|
|
21
23
|
const { t } = useTranslation();
|
|
22
24
|
const { settingsPage, setSettingsPage, settingsActiveSubTab, setSettingsActiveSubTab, tabVisibility, toggleTabVisibility, defaultTab, setDefaultTab, isDark, setIsDark, modalHeightPercent, setModalHeightPercent, modalAnimationType, setModalAnimationType, showDuplicateLogs, setShowDuplicateLogs, showConsoleLevels, setShowConsoleLevels, resetToDefaults, storage, logs, consoleLogs, analyticsEvents, reduxState, maxNetworkLogs, setMaxNetworkLogs, maxConsoleLogs, setMaxConsoleLogs, reduxAutoRefresh, setReduxAutoRefreshState, reduxExpandDepth, setReduxExpandDepth, switchActiveTab, setSelected, setSelectedEvent, setReduxState, crashRecords, maxCrashLogs, setMaxCrashLogs, } = useInspector();
|
|
23
25
|
const isPersistent = isPersistentStorageAvailable();
|
|
24
|
-
|
|
26
|
+
// Safe Area & Status Bar Padding for All Device Form Factors
|
|
27
|
+
const statusBarHeight = Platform.OS === 'android' ? StatusBar.currentHeight || 24 : 44;
|
|
28
|
+
const headerTopPadding = modalHeightPercent >= 95 ? statusBarHeight : 0;
|
|
29
|
+
const allModules = [
|
|
30
|
+
{
|
|
31
|
+
key: 'apis',
|
|
32
|
+
label: 'APIs (Network)',
|
|
33
|
+
category: 'core',
|
|
34
|
+
icon: 'apis',
|
|
35
|
+
desc: 'HTTP/HTTPS requests, GraphQL, Axios & WebSocket inspector',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: 'logs',
|
|
39
|
+
label: 'Console Logs',
|
|
40
|
+
category: 'core',
|
|
41
|
+
icon: 'logs',
|
|
42
|
+
desc: 'Terminal console logs, warnings, errors & stack traces',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
key: 'performance',
|
|
46
|
+
label: 'Performance Tracker',
|
|
47
|
+
category: 'diagnostic',
|
|
48
|
+
icon: 'performance',
|
|
49
|
+
desc: '60 FPS monitor, Hermes memory telemetry & re-render profiler',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: 'bundle',
|
|
53
|
+
label: 'Bundle Analyzer',
|
|
54
|
+
category: 'diagnostic',
|
|
55
|
+
icon: 'bundle',
|
|
56
|
+
desc: 'Metro packager dependencies, source maps & asset breakdown',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
key: 'crash',
|
|
60
|
+
label: 'Crash Protection',
|
|
61
|
+
category: 'diagnostic',
|
|
62
|
+
icon: 'crash',
|
|
63
|
+
desc: 'Runtime exception guard, breadcrumbs & memory snapshot',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
key: 'analytics',
|
|
67
|
+
label: 'Analytics Logger',
|
|
68
|
+
category: 'telemetry',
|
|
69
|
+
icon: 'analytics',
|
|
70
|
+
desc: 'Firebase & custom analytics events, user properties & params',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
key: 'redux',
|
|
74
|
+
label: 'Redux Inspector',
|
|
75
|
+
category: 'telemetry',
|
|
76
|
+
icon: 'redux',
|
|
77
|
+
desc: 'Store state diffing, action history & reducer timeline',
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
// Staged selection state for checkboxes before clicking "Save Changes"
|
|
81
|
+
const [stagedTabVisibility, setStagedTabVisibility] = useState(() => ({
|
|
82
|
+
apis: true,
|
|
83
|
+
logs: Boolean(tabVisibility?.logs),
|
|
84
|
+
analytics: Boolean(tabVisibility?.analytics),
|
|
85
|
+
redux: Boolean(tabVisibility?.redux),
|
|
86
|
+
bundle: Boolean(tabVisibility?.bundle),
|
|
87
|
+
performance: Boolean(tabVisibility?.performance),
|
|
88
|
+
crash: Boolean(tabVisibility?.crash),
|
|
89
|
+
}));
|
|
90
|
+
// Synchronize staged state with tabVisibility when tabVisibility updates
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
setStagedTabVisibility({
|
|
93
|
+
apis: true,
|
|
94
|
+
logs: Boolean(tabVisibility?.logs),
|
|
95
|
+
analytics: Boolean(tabVisibility?.analytics),
|
|
96
|
+
redux: Boolean(tabVisibility?.redux),
|
|
97
|
+
bundle: Boolean(tabVisibility?.bundle),
|
|
98
|
+
performance: Boolean(tabVisibility?.performance),
|
|
99
|
+
crash: Boolean(tabVisibility?.crash),
|
|
100
|
+
});
|
|
101
|
+
}, [tabVisibility]);
|
|
102
|
+
const hasUnsavedChanges = useMemo(() => {
|
|
103
|
+
return allModules.some(m => Boolean(stagedTabVisibility[m.key]) !==
|
|
104
|
+
Boolean(tabVisibility?.[m.key]));
|
|
105
|
+
}, [stagedTabVisibility, tabVisibility, allModules]);
|
|
106
|
+
const stagedActiveCount = allModules.filter(m => m.key === 'apis' || Boolean(stagedTabVisibility[m.key])).length;
|
|
107
|
+
const handleSaveChanges = () => {
|
|
108
|
+
animateNextLayout();
|
|
109
|
+
allModules.forEach(m => {
|
|
110
|
+
if (m.key !== 'apis') {
|
|
111
|
+
const isStagedOn = Boolean(stagedTabVisibility[m.key]);
|
|
112
|
+
const isCurrentOn = Boolean(tabVisibility?.[m.key]);
|
|
113
|
+
if (isStagedOn !== isCurrentOn) {
|
|
114
|
+
toggleTabVisibility(m.key);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
Alert.alert(t('settings.settingsSaved'), t('settings.settingsSavedDesc'));
|
|
119
|
+
};
|
|
25
120
|
if (settingsPage === 'main') {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
{ key: 'bundle', label: 'Bundle', icon: 'bundle' },
|
|
32
|
-
{ key: 'performance', label: 'Performance', icon: 'performance' },
|
|
33
|
-
{ key: 'crash', label: 'Crash', icon: 'crash' },
|
|
34
|
-
];
|
|
35
|
-
return (<View style={{ flex: 1, backgroundColor: AppColors.grayBackground }}>
|
|
36
|
-
{/* Settings Header with back button */}
|
|
121
|
+
return (<View style={{
|
|
122
|
+
flex: 1,
|
|
123
|
+
backgroundColor: AppColors.grayBackground,
|
|
124
|
+
}}>
|
|
125
|
+
{/* Modern Floating Gradient Header */}
|
|
37
126
|
<LinearGradient colors={[AppColors.purple, AppColors.brandPurple]} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles.headerGradient}>
|
|
38
127
|
<View style={{ paddingTop: headerTopPadding, width: '100%' }}>
|
|
39
|
-
<View style={[
|
|
40
|
-
|
|
128
|
+
<View style={[
|
|
129
|
+
styles.header,
|
|
130
|
+
{ paddingHorizontal: 16, paddingVertical: 12, gap: 12 },
|
|
131
|
+
]}>
|
|
132
|
+
<TouchableScale accessible={true} accessibilityRole="button" accessibilityLabel={t('settings.back')} onPress={() => {
|
|
41
133
|
animateNextLayout();
|
|
42
134
|
setSettingsPage(null);
|
|
43
135
|
switchActiveTab('apis');
|
|
@@ -46,223 +138,360 @@ const SettingsPanel = () => {
|
|
|
46
138
|
borderRadius: 10,
|
|
47
139
|
backgroundColor: `${AppColors.white}26`,
|
|
48
140
|
borderWidth: 1,
|
|
49
|
-
borderColor: `${AppColors.white}
|
|
141
|
+
borderColor: `${AppColors.white}18`,
|
|
50
142
|
}}>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<
|
|
143
|
+
<WhiteBackNavigation color={AppColors.white} size={16}/>
|
|
144
|
+
</TouchableScale>
|
|
145
|
+
|
|
146
|
+
<View style={{ flex: 1 }}>
|
|
147
|
+
<View style={{
|
|
148
|
+
flexDirection: 'row',
|
|
149
|
+
alignItems: 'center',
|
|
150
|
+
gap: 8,
|
|
151
|
+
}}>
|
|
152
|
+
<Text style={{
|
|
55
153
|
fontFamily: AppFonts.interBold,
|
|
56
154
|
fontSize: 17,
|
|
57
155
|
color: AppColors.white,
|
|
156
|
+
letterSpacing: -0.3,
|
|
157
|
+
lineHeight: 22,
|
|
58
158
|
}}>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
159
|
+
{t('settings.mainTitle')}
|
|
160
|
+
</Text>
|
|
161
|
+
<View style={{
|
|
162
|
+
backgroundColor: `${AppColors.white}26`,
|
|
163
|
+
paddingHorizontal: 7,
|
|
164
|
+
paddingVertical: 2,
|
|
165
|
+
borderRadius: 12,
|
|
166
|
+
}}>
|
|
167
|
+
<Text style={{
|
|
168
|
+
fontFamily: AppFonts.interBold,
|
|
169
|
+
fontSize: 10,
|
|
170
|
+
color: AppColors.white,
|
|
171
|
+
lineHeight: 13,
|
|
172
|
+
}}>
|
|
173
|
+
{stagedActiveCount}/{allModules.length} Active
|
|
174
|
+
</Text>
|
|
175
|
+
</View>
|
|
176
|
+
</View>
|
|
177
|
+
<Text style={{
|
|
62
178
|
fontFamily: AppFonts.interRegular,
|
|
63
179
|
fontSize: 11,
|
|
64
|
-
color: `${AppColors.white}
|
|
65
|
-
marginTop:
|
|
180
|
+
color: `${AppColors.white}CC`,
|
|
181
|
+
marginTop: 2,
|
|
182
|
+
lineHeight: 15,
|
|
66
183
|
}}>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
184
|
+
{t('settings.mainSubtitle')}
|
|
185
|
+
</Text>
|
|
186
|
+
</View>
|
|
187
|
+
|
|
188
|
+
<View style={{
|
|
189
|
+
backgroundColor: `${AppColors.white}22`,
|
|
72
190
|
paddingHorizontal: 8,
|
|
73
191
|
paddingVertical: 4,
|
|
74
192
|
borderRadius: 8,
|
|
75
193
|
borderWidth: 1,
|
|
76
194
|
borderColor: `${AppColors.white}1A`,
|
|
77
195
|
}}>
|
|
78
|
-
|
|
196
|
+
<Text style={{
|
|
79
197
|
fontFamily: AppFonts.interBold,
|
|
80
198
|
fontSize: 10.5,
|
|
81
199
|
color: AppColors.white,
|
|
200
|
+
lineHeight: 14,
|
|
82
201
|
}}>
|
|
83
|
-
|
|
84
|
-
|
|
202
|
+
v{LIB_VERSION}
|
|
203
|
+
</Text>
|
|
204
|
+
</View>
|
|
85
205
|
</View>
|
|
86
206
|
</View>
|
|
87
|
-
</
|
|
88
|
-
</LinearGradient>
|
|
207
|
+
</LinearGradient>
|
|
89
208
|
|
|
90
|
-
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap:
|
|
91
|
-
{/* Sub
|
|
209
|
+
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 14 }} showsVerticalScrollIndicator={false}>
|
|
210
|
+
{/* Segmented Top Navigation Sub-Tabs */}
|
|
92
211
|
<View style={{
|
|
93
212
|
flexDirection: 'row',
|
|
94
213
|
backgroundColor: AppColors.primaryLight,
|
|
95
|
-
borderRadius:
|
|
96
|
-
padding:
|
|
214
|
+
borderRadius: 12,
|
|
215
|
+
padding: 4,
|
|
97
216
|
borderWidth: 1,
|
|
98
217
|
borderColor: AppColors.grayBorderSecondary,
|
|
99
|
-
|
|
218
|
+
shadowColor: AppColors.black,
|
|
219
|
+
shadowOpacity: 0.04,
|
|
220
|
+
shadowRadius: 4,
|
|
221
|
+
shadowOffset: { width: 0, height: 2 },
|
|
100
222
|
}}>
|
|
101
|
-
<
|
|
223
|
+
<TouchableScale accessible={true} accessibilityRole="tab" accessibilityLabel={t('settings.modulesAndTools')} accessibilityState={{ selected: settingsActiveSubTab === 'module' }} onPress={() => {
|
|
102
224
|
animateNextLayout();
|
|
103
225
|
setSettingsActiveSubTab('module');
|
|
104
226
|
}} style={{
|
|
105
227
|
flex: 1,
|
|
106
|
-
paddingVertical:
|
|
228
|
+
paddingVertical: 9,
|
|
229
|
+
flexDirection: 'row',
|
|
107
230
|
alignItems: 'center',
|
|
108
231
|
justifyContent: 'center',
|
|
109
|
-
|
|
232
|
+
gap: 6,
|
|
233
|
+
borderRadius: 9,
|
|
110
234
|
backgroundColor: settingsActiveSubTab === 'module'
|
|
111
235
|
? AppColors.purple
|
|
112
236
|
: 'transparent',
|
|
113
237
|
}}>
|
|
238
|
+
<LayersIcon color={settingsActiveSubTab === 'module'
|
|
239
|
+
? AppColors.white
|
|
240
|
+
: AppColors.grayText} size={13}/>
|
|
114
241
|
<Text style={{
|
|
115
242
|
fontFamily: AppFonts.interBold,
|
|
116
|
-
fontSize: 12,
|
|
243
|
+
fontSize: 12.5,
|
|
244
|
+
lineHeight: 16,
|
|
117
245
|
color: settingsActiveSubTab === 'module'
|
|
118
246
|
? AppColors.white
|
|
119
247
|
: AppColors.grayText,
|
|
120
248
|
}}>
|
|
121
|
-
|
|
249
|
+
{t('settings.modulesAndTools')}
|
|
122
250
|
</Text>
|
|
123
|
-
</
|
|
124
|
-
|
|
251
|
+
</TouchableScale>
|
|
252
|
+
|
|
253
|
+
<TouchableScale accessible={true} accessibilityRole="tab" accessibilityLabel={t('settings.uiPreferences')} accessibilityState={{ selected: settingsActiveSubTab === 'ui' }} onPress={() => {
|
|
125
254
|
animateNextLayout();
|
|
126
255
|
setSettingsActiveSubTab('ui');
|
|
127
256
|
}} style={{
|
|
128
257
|
flex: 1,
|
|
129
|
-
paddingVertical:
|
|
258
|
+
paddingVertical: 9,
|
|
259
|
+
flexDirection: 'row',
|
|
130
260
|
alignItems: 'center',
|
|
131
261
|
justifyContent: 'center',
|
|
132
|
-
|
|
262
|
+
gap: 6,
|
|
263
|
+
borderRadius: 9,
|
|
133
264
|
backgroundColor: settingsActiveSubTab === 'ui'
|
|
134
265
|
? AppColors.purple
|
|
135
266
|
: 'transparent',
|
|
136
267
|
}}>
|
|
268
|
+
<ScreenIcon color={settingsActiveSubTab === 'ui'
|
|
269
|
+
? AppColors.white
|
|
270
|
+
: AppColors.grayText} size={13}/>
|
|
137
271
|
<Text style={{
|
|
138
272
|
fontFamily: AppFonts.interBold,
|
|
139
|
-
fontSize: 12,
|
|
273
|
+
fontSize: 12.5,
|
|
274
|
+
lineHeight: 16,
|
|
140
275
|
color: settingsActiveSubTab === 'ui'
|
|
141
276
|
? AppColors.white
|
|
142
277
|
: AppColors.grayText,
|
|
143
278
|
}}>
|
|
144
|
-
|
|
279
|
+
{t('settings.uiPreferences')}
|
|
145
280
|
</Text>
|
|
146
|
-
</
|
|
281
|
+
</TouchableScale>
|
|
147
282
|
</View>
|
|
148
283
|
|
|
149
|
-
{settingsActiveSubTab === 'module' ? (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
backgroundColor: AppColors.
|
|
284
|
+
{settingsActiveSubTab === 'module' ? (<View style={{ gap: 12 }}>
|
|
285
|
+
{/* Performance Advisory Banner */}
|
|
286
|
+
<View style={{
|
|
287
|
+
backgroundColor: `${AppColors.purple}0A`,
|
|
153
288
|
borderRadius: 12,
|
|
289
|
+
padding: 12,
|
|
154
290
|
borderWidth: 1,
|
|
155
|
-
borderColor: AppColors.
|
|
156
|
-
overflow: 'hidden',
|
|
157
|
-
}}>
|
|
158
|
-
{/* Table Header */}
|
|
159
|
-
<View style={{
|
|
291
|
+
borderColor: `${AppColors.purple}20`,
|
|
160
292
|
flexDirection: 'row',
|
|
161
293
|
alignItems: 'center',
|
|
162
|
-
|
|
163
|
-
paddingHorizontal: 14,
|
|
164
|
-
backgroundColor: AppColors.grayBackground,
|
|
165
|
-
borderBottomWidth: 1,
|
|
166
|
-
borderBottomColor: AppColors.dividerColor,
|
|
167
|
-
gap: 12,
|
|
294
|
+
gap: 10,
|
|
168
295
|
}}>
|
|
169
|
-
<
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
296
|
+
<View style={{
|
|
297
|
+
width: 32,
|
|
298
|
+
height: 32,
|
|
299
|
+
borderRadius: 8,
|
|
300
|
+
backgroundColor: `${AppColors.purple}14`,
|
|
301
|
+
alignItems: 'center',
|
|
302
|
+
justifyContent: 'center',
|
|
175
303
|
}}>
|
|
176
|
-
|
|
177
|
-
</
|
|
178
|
-
<
|
|
304
|
+
<SignalIcon color={AppColors.purple} size={15}/>
|
|
305
|
+
</View>
|
|
306
|
+
<View style={{ flex: 1 }}>
|
|
307
|
+
<Text style={{
|
|
179
308
|
fontFamily: AppFonts.interBold,
|
|
180
|
-
fontSize:
|
|
181
|
-
color: AppColors.
|
|
182
|
-
|
|
183
|
-
width: 90,
|
|
184
|
-
textAlign: 'right',
|
|
185
|
-
paddingRight: 4,
|
|
309
|
+
fontSize: 12,
|
|
310
|
+
color: AppColors.primaryBlack,
|
|
311
|
+
lineHeight: 16,
|
|
186
312
|
}}>
|
|
187
|
-
|
|
188
|
-
|
|
313
|
+
{t('settings.zeroOverheadTitle')}
|
|
314
|
+
</Text>
|
|
315
|
+
<Text style={{
|
|
316
|
+
fontFamily: AppFonts.interRegular,
|
|
317
|
+
fontSize: 10.5,
|
|
318
|
+
color: AppColors.grayText,
|
|
319
|
+
marginTop: 2,
|
|
320
|
+
lineHeight: 14,
|
|
321
|
+
}}>
|
|
322
|
+
{t('settings.zeroOverheadDesc')}
|
|
323
|
+
</Text>
|
|
324
|
+
</View>
|
|
189
325
|
</View>
|
|
190
326
|
|
|
191
|
-
{
|
|
327
|
+
{/* Enhanced Individual Module Cards with Decorative Checkboxes */}
|
|
328
|
+
<View style={{ gap: 10 }}>
|
|
329
|
+
{allModules.map(moduleItem => {
|
|
192
330
|
const isReduxAvail = isReduxConnected();
|
|
193
331
|
const isAnalyticsAvail = isAnalyticsConnected();
|
|
194
|
-
const isUnavailable = (
|
|
195
|
-
(
|
|
196
|
-
const isLocked =
|
|
197
|
-
const
|
|
198
|
-
(Boolean(
|
|
199
|
-
|
|
200
|
-
|
|
332
|
+
const isUnavailable = (moduleItem.key === 'redux' && !isReduxAvail) ||
|
|
333
|
+
(moduleItem.key === 'analytics' && !isAnalyticsAvail);
|
|
334
|
+
const isLocked = moduleItem.key === 'apis' || isUnavailable;
|
|
335
|
+
const isChecked = moduleItem.key === 'apis' ||
|
|
336
|
+
(Boolean(stagedTabVisibility?.[moduleItem.key]) &&
|
|
337
|
+
!isUnavailable);
|
|
338
|
+
const liveStats = moduleItem.key === 'apis'
|
|
339
|
+
? `${logs.length} requests • Limit: ${maxNetworkLogs}`
|
|
340
|
+
: moduleItem.key === 'logs'
|
|
341
|
+
? `${consoleLogs.length} logs • Limit: ${maxConsoleLogs}`
|
|
342
|
+
: moduleItem.key === 'performance'
|
|
343
|
+
? '60 FPS Target • Memory Telemetry'
|
|
344
|
+
: moduleItem.key === 'bundle'
|
|
345
|
+
? 'Metro Packager • Dependency Map'
|
|
346
|
+
: moduleItem.key === 'crash'
|
|
347
|
+
? `${crashRecords?.length || 0} crashes recorded • Crash Guard`
|
|
348
|
+
: moduleItem.key === 'analytics'
|
|
349
|
+
? `${analyticsEvents.length} events logged`
|
|
350
|
+
: moduleItem.key === 'redux'
|
|
351
|
+
? `${Object.keys(reduxState || {}).length} slices • Depth: ${reduxExpandDepth}`
|
|
352
|
+
: '';
|
|
353
|
+
return (<View key={moduleItem.key} style={{
|
|
354
|
+
backgroundColor: AppColors.primaryLight,
|
|
355
|
+
borderRadius: 14,
|
|
356
|
+
borderWidth: 1.5,
|
|
357
|
+
borderColor: isChecked
|
|
358
|
+
? `${AppColors.purple}38`
|
|
359
|
+
: AppColors.grayBorderSecondary,
|
|
360
|
+
padding: 14,
|
|
361
|
+
gap: 10,
|
|
362
|
+
shadowColor: AppColors.black,
|
|
363
|
+
shadowOpacity: isChecked ? 0.04 : 0.02,
|
|
364
|
+
shadowRadius: 5,
|
|
365
|
+
shadowOffset: { width: 0, height: 2 },
|
|
366
|
+
}}>
|
|
367
|
+
{/* Top Row: Icon + Title & Badges + Checkbox */}
|
|
368
|
+
<View style={{
|
|
201
369
|
flexDirection: 'row',
|
|
202
|
-
alignItems: '
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
borderBottomWidth: isLast ? 0 : 1,
|
|
206
|
-
borderBottomColor: AppColors.dividerColor,
|
|
207
|
-
gap: 12,
|
|
370
|
+
alignItems: 'flex-start',
|
|
371
|
+
justifyContent: 'space-between',
|
|
372
|
+
gap: 10,
|
|
208
373
|
}}>
|
|
209
|
-
|
|
210
|
-
|
|
374
|
+
{/* Tap Zone for Details/Settings */}
|
|
375
|
+
<TouchableScale accessible={true} accessibilityRole="button" accessibilityLabel={`${moduleItem.label} settings`} disabled={isUnavailable} onPress={() => {
|
|
376
|
+
animateNextLayout();
|
|
377
|
+
setSettingsPage(moduleItem.key);
|
|
378
|
+
}} style={{
|
|
211
379
|
flex: 1,
|
|
212
380
|
flexDirection: 'row',
|
|
213
|
-
alignItems: '
|
|
214
|
-
gap:
|
|
215
|
-
flexWrap: 'wrap',
|
|
381
|
+
alignItems: 'flex-start',
|
|
382
|
+
gap: 10,
|
|
216
383
|
}}>
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
width:
|
|
220
|
-
height:
|
|
221
|
-
borderRadius:
|
|
384
|
+
{/* Icon Tile */}
|
|
385
|
+
<View style={{
|
|
386
|
+
width: 36,
|
|
387
|
+
height: 36,
|
|
388
|
+
borderRadius: 10,
|
|
222
389
|
backgroundColor: isLocked
|
|
223
|
-
? AppColors.grayBorderSecondary
|
|
224
|
-
:
|
|
390
|
+
? `${AppColors.grayBorderSecondary}4D`
|
|
391
|
+
: isChecked
|
|
392
|
+
? `${AppColors.purple}14`
|
|
393
|
+
: AppColors.grayBackground,
|
|
225
394
|
borderWidth: 1,
|
|
226
395
|
borderColor: isLocked
|
|
227
396
|
? AppColors.dividerColor
|
|
228
|
-
:
|
|
397
|
+
: isChecked
|
|
398
|
+
? `${AppColors.purple}33`
|
|
399
|
+
: AppColors.grayBorderSecondary,
|
|
229
400
|
alignItems: 'center',
|
|
230
401
|
justifyContent: 'center',
|
|
402
|
+
marginTop: 1,
|
|
231
403
|
}}>
|
|
232
|
-
|
|
233
|
-
? AppColors.
|
|
234
|
-
: AppColors.
|
|
235
|
-
|
|
236
|
-
? AppColors.
|
|
237
|
-
: AppColors.
|
|
238
|
-
|
|
239
|
-
? AppColors.
|
|
240
|
-
: AppColors.
|
|
241
|
-
|
|
242
|
-
? AppColors.
|
|
243
|
-
: AppColors.
|
|
244
|
-
|
|
245
|
-
? AppColors.
|
|
246
|
-
: AppColors.
|
|
247
|
-
|
|
248
|
-
? AppColors.
|
|
249
|
-
: AppColors.
|
|
250
|
-
|
|
251
|
-
? AppColors.
|
|
252
|
-
: AppColors.
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
404
|
+
{moduleItem.icon === 'apis' && (<SignalIcon color={isChecked
|
|
405
|
+
? AppColors.purple
|
|
406
|
+
: AppColors.grayTextWeak} size={16}/>)}
|
|
407
|
+
{moduleItem.icon === 'logs' && (<TerminalIcon color={isChecked
|
|
408
|
+
? AppColors.purple
|
|
409
|
+
: AppColors.grayTextWeak} size={16}/>)}
|
|
410
|
+
{moduleItem.icon === 'performance' && (<PerformanceIcon color={isChecked
|
|
411
|
+
? AppColors.purple
|
|
412
|
+
: AppColors.grayTextWeak} size={16}/>)}
|
|
413
|
+
{moduleItem.icon === 'bundle' && (<PackageIcon color={isChecked
|
|
414
|
+
? AppColors.purple
|
|
415
|
+
: AppColors.grayTextWeak} size={16}/>)}
|
|
416
|
+
{moduleItem.icon === 'crash' && (<CrashIcon color={isChecked
|
|
417
|
+
? AppColors.purple
|
|
418
|
+
: AppColors.grayTextWeak} size={16}/>)}
|
|
419
|
+
{moduleItem.icon === 'analytics' && (<AnalyticsIcon color={isChecked
|
|
420
|
+
? AppColors.purple
|
|
421
|
+
: AppColors.grayTextWeak} size={16}/>)}
|
|
422
|
+
{moduleItem.icon === 'redux' && (<ReduxIcon color={isChecked
|
|
423
|
+
? AppColors.purple
|
|
424
|
+
: AppColors.grayTextWeak} size={16}/>)}
|
|
425
|
+
</View>
|
|
426
|
+
|
|
427
|
+
{/* Titles & Status Pill */}
|
|
428
|
+
<View style={{ flex: 1, gap: 2 }}>
|
|
429
|
+
<View style={{
|
|
430
|
+
flexDirection: 'row',
|
|
431
|
+
alignItems: 'center',
|
|
432
|
+
gap: 6,
|
|
433
|
+
flexWrap: 'wrap',
|
|
434
|
+
}}>
|
|
435
|
+
<Text style={{
|
|
256
436
|
fontFamily: AppFonts.interBold,
|
|
257
|
-
fontSize:
|
|
437
|
+
fontSize: 14,
|
|
438
|
+
lineHeight: 18,
|
|
258
439
|
color: isLocked
|
|
259
440
|
? AppColors.grayText
|
|
260
441
|
: AppColors.primaryBlack,
|
|
261
442
|
}}>
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
443
|
+
{moduleItem.label}
|
|
444
|
+
</Text>
|
|
445
|
+
|
|
446
|
+
{/* Default Startup Tab Badge */}
|
|
447
|
+
{moduleItem.key === defaultTab &&
|
|
448
|
+
!isUnavailable && (<View style={{
|
|
449
|
+
flexDirection: 'row',
|
|
450
|
+
alignItems: 'center',
|
|
451
|
+
backgroundColor: `${AppColors.purple}14`,
|
|
452
|
+
borderRadius: 12,
|
|
453
|
+
paddingHorizontal: 5,
|
|
454
|
+
paddingVertical: 1.5,
|
|
455
|
+
borderWidth: 1,
|
|
456
|
+
borderColor: `${AppColors.purple}2E`,
|
|
457
|
+
gap: 3,
|
|
458
|
+
}}>
|
|
459
|
+
<View style={{
|
|
460
|
+
width: 4,
|
|
461
|
+
height: 4,
|
|
462
|
+
borderRadius: 2,
|
|
463
|
+
backgroundColor: AppColors.purple,
|
|
464
|
+
}}/>
|
|
465
|
+
<Text style={{
|
|
466
|
+
fontFamily: AppFonts.interBold,
|
|
467
|
+
fontSize: 8,
|
|
468
|
+
lineHeight: 11,
|
|
469
|
+
color: AppColors.purple,
|
|
470
|
+
letterSpacing: 0.4,
|
|
471
|
+
}}>
|
|
472
|
+
{t('settings.defaultBadge')}
|
|
473
|
+
</Text>
|
|
474
|
+
</View>)}
|
|
475
|
+
|
|
476
|
+
{/* Status Pill */}
|
|
477
|
+
{moduleItem.key === 'apis' ? (<View style={{
|
|
478
|
+
backgroundColor: `${AppColors.blue500}14`,
|
|
479
|
+
borderRadius: 4,
|
|
480
|
+
paddingHorizontal: 5,
|
|
481
|
+
paddingVertical: 1.5,
|
|
482
|
+
borderWidth: 1,
|
|
483
|
+
borderColor: `${AppColors.blue500}33`,
|
|
484
|
+
}}>
|
|
485
|
+
<Text style={{
|
|
486
|
+
fontFamily: AppFonts.interBold,
|
|
487
|
+
fontSize: 8,
|
|
488
|
+
lineHeight: 11,
|
|
489
|
+
color: AppColors.blue500,
|
|
490
|
+
letterSpacing: 0.3,
|
|
491
|
+
}}>
|
|
492
|
+
{t('settings.coreBadge')}
|
|
493
|
+
</Text>
|
|
494
|
+
</View>) : isUnavailable ? (<View style={{
|
|
266
495
|
backgroundColor: `${AppColors.amber500}18`,
|
|
267
496
|
borderRadius: 4,
|
|
268
497
|
paddingHorizontal: 5,
|
|
@@ -270,181 +499,244 @@ const SettingsPanel = () => {
|
|
|
270
499
|
borderWidth: 1,
|
|
271
500
|
borderColor: `${AppColors.amber500}35`,
|
|
272
501
|
}}>
|
|
273
|
-
|
|
502
|
+
<Text style={{
|
|
274
503
|
fontFamily: AppFonts.interBold,
|
|
275
504
|
fontSize: 8,
|
|
505
|
+
lineHeight: 11,
|
|
276
506
|
color: AppColors.amber700,
|
|
277
507
|
letterSpacing: 0.3,
|
|
278
508
|
}}>
|
|
279
|
-
|
|
509
|
+
{moduleItem.key === 'redux'
|
|
280
510
|
? t('settings.notConnectedBadge')
|
|
281
511
|
: t('settings.notDetectedBadge')}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
backgroundColor: `${AppColors.purple}14`,
|
|
289
|
-
borderRadius: 20,
|
|
290
|
-
paddingHorizontal: 6,
|
|
291
|
-
paddingVertical: 2,
|
|
512
|
+
</Text>
|
|
513
|
+
</View>) : isChecked ? (<View style={{
|
|
514
|
+
backgroundColor: `${AppColors.liveGreen}18`,
|
|
515
|
+
borderRadius: 4,
|
|
516
|
+
paddingHorizontal: 5,
|
|
517
|
+
paddingVertical: 1.5,
|
|
292
518
|
borderWidth: 1,
|
|
293
|
-
borderColor: `${AppColors.
|
|
294
|
-
gap: 3,
|
|
519
|
+
borderColor: `${AppColors.liveGreen}38`,
|
|
295
520
|
}}>
|
|
296
|
-
|
|
297
|
-
width: 4,
|
|
298
|
-
height: 4,
|
|
299
|
-
borderRadius: 2,
|
|
300
|
-
backgroundColor: AppColors.purple,
|
|
301
|
-
opacity: 0.7,
|
|
302
|
-
}}/>
|
|
303
|
-
<Text style={{
|
|
521
|
+
<Text style={{
|
|
304
522
|
fontFamily: AppFonts.interBold,
|
|
305
|
-
fontSize: 8
|
|
306
|
-
|
|
307
|
-
|
|
523
|
+
fontSize: 8,
|
|
524
|
+
lineHeight: 11,
|
|
525
|
+
color: AppColors.green700,
|
|
526
|
+
letterSpacing: 0.3,
|
|
308
527
|
}}>
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
setSettingsPage(tab.key);
|
|
317
|
-
}} hitSlop={8} style={{
|
|
318
|
-
marginLeft: 4,
|
|
319
|
-
padding: 4,
|
|
320
|
-
borderRadius: 6,
|
|
321
|
-
backgroundColor: AppColors.purpleShade50,
|
|
528
|
+
{t('settings.activeBadge')}
|
|
529
|
+
</Text>
|
|
530
|
+
</View>) : (<View style={{
|
|
531
|
+
backgroundColor: `${AppColors.grayTextWeak}18`,
|
|
532
|
+
borderRadius: 4,
|
|
533
|
+
paddingHorizontal: 5,
|
|
534
|
+
paddingVertical: 1.5,
|
|
322
535
|
borderWidth: 1,
|
|
323
|
-
borderColor: `${AppColors.
|
|
324
|
-
alignItems: 'center',
|
|
325
|
-
justifyContent: 'center',
|
|
536
|
+
borderColor: `${AppColors.grayTextWeak}2E`,
|
|
326
537
|
}}>
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
538
|
+
<Text style={{
|
|
539
|
+
fontFamily: AppFonts.interBold,
|
|
540
|
+
fontSize: 8,
|
|
541
|
+
lineHeight: 11,
|
|
542
|
+
color: AppColors.grayTextWeak,
|
|
543
|
+
letterSpacing: 0.3,
|
|
544
|
+
}}>
|
|
545
|
+
{t('settings.dormantBadge')}
|
|
546
|
+
</Text>
|
|
547
|
+
</View>)}
|
|
548
|
+
</View>
|
|
330
549
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
550
|
+
<Text style={{
|
|
551
|
+
fontFamily: AppFonts.interRegular,
|
|
552
|
+
fontSize: 11,
|
|
553
|
+
color: AppColors.grayText,
|
|
554
|
+
lineHeight: 15,
|
|
555
|
+
marginTop: 1,
|
|
336
556
|
}}>
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
557
|
+
{moduleItem.desc}
|
|
558
|
+
</Text>
|
|
559
|
+
</View>
|
|
560
|
+
</TouchableScale>
|
|
561
|
+
|
|
562
|
+
{/* Decorative Custom Checkbox */}
|
|
563
|
+
<TouchableScale accessible={true} accessibilityRole="checkbox" accessibilityLabel={`Select ${moduleItem.label}`} accessibilityState={{
|
|
564
|
+
checked: isChecked,
|
|
565
|
+
disabled: isLocked,
|
|
566
|
+
}} disabled={isLocked} onPress={() => {
|
|
567
|
+
if (isLocked)
|
|
568
|
+
return;
|
|
569
|
+
setStagedTabVisibility(prev => ({
|
|
570
|
+
...prev,
|
|
571
|
+
[moduleItem.key]: !prev[moduleItem.key],
|
|
572
|
+
}));
|
|
573
|
+
}} style={{
|
|
574
|
+
width: 26,
|
|
575
|
+
height: 26,
|
|
576
|
+
borderRadius: 8,
|
|
577
|
+
borderWidth: isChecked ? 0 : 2,
|
|
347
578
|
borderColor: isLocked
|
|
348
|
-
? AppColors.
|
|
349
|
-
:
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}}>
|
|
356
|
-
<View style={{
|
|
357
|
-
width: 18,
|
|
358
|
-
height: 18,
|
|
359
|
-
borderRadius: 9,
|
|
360
|
-
backgroundColor: isLocked
|
|
361
|
-
? AppColors.grayBorderSecondary
|
|
362
|
-
: AppColors.white,
|
|
579
|
+
? AppColors.dividerColor
|
|
580
|
+
: AppColors.grayBorderSecondary,
|
|
581
|
+
backgroundColor: moduleItem.key === 'apis'
|
|
582
|
+
? `${AppColors.blue500}22`
|
|
583
|
+
: isChecked
|
|
584
|
+
? AppColors.purple
|
|
585
|
+
: AppColors.grayBackground,
|
|
363
586
|
alignItems: 'center',
|
|
364
587
|
justifyContent: 'center',
|
|
365
|
-
shadowColor:
|
|
366
|
-
|
|
367
|
-
|
|
588
|
+
shadowColor: isChecked
|
|
589
|
+
? AppColors.purple
|
|
590
|
+
: 'transparent',
|
|
591
|
+
shadowOpacity: isChecked ? 0.3 : 0,
|
|
592
|
+
shadowRadius: 3,
|
|
368
593
|
shadowOffset: { width: 0, height: 1 },
|
|
594
|
+
elevation: isChecked ? 2 : 0,
|
|
369
595
|
}}>
|
|
370
|
-
{isLocked
|
|
596
|
+
{moduleItem.key === 'apis' ? (<CheckIcon size={14} color={AppColors.blue500}/>) : isChecked ? (<CheckIcon size={14} color={AppColors.white}/>) : isLocked ? (<Svg width={10} height={10} viewBox="0 0 24 24" fill="none">
|
|
371
597
|
<Path d="M7 10V7a5 5 0 0 1 10 0v3" stroke={AppColors.grayText} strokeWidth="2.2" strokeLinecap="round"/>
|
|
372
598
|
<Path d="M5 10h14v9a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1z" fill={AppColors.grayText}/>
|
|
373
|
-
</Svg>)}
|
|
374
|
-
</
|
|
375
|
-
</
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
599
|
+
</Svg>) : null}
|
|
600
|
+
</TouchableScale>
|
|
601
|
+
</View>
|
|
602
|
+
|
|
603
|
+
{/* Card Footer: Live Stats + Configure Button */}
|
|
604
|
+
{!isUnavailable && (<View style={{
|
|
605
|
+
flexDirection: 'row',
|
|
606
|
+
alignItems: 'center',
|
|
607
|
+
justifyContent: 'space-between',
|
|
608
|
+
paddingTop: 8,
|
|
609
|
+
borderTopWidth: 1,
|
|
610
|
+
borderTopColor: AppColors.dividerColor,
|
|
611
|
+
}}>
|
|
612
|
+
{/* Live Info Pill */}
|
|
613
|
+
<View style={{
|
|
614
|
+
flexDirection: 'row',
|
|
615
|
+
alignItems: 'center',
|
|
616
|
+
gap: 6,
|
|
617
|
+
flex: 1,
|
|
618
|
+
}}>
|
|
619
|
+
<View style={{
|
|
620
|
+
width: 6,
|
|
621
|
+
height: 6,
|
|
622
|
+
borderRadius: 3,
|
|
623
|
+
backgroundColor: isChecked
|
|
624
|
+
? AppColors.liveGreen
|
|
381
625
|
: AppColors.grayTextWeak,
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
626
|
+
}}/>
|
|
627
|
+
<Text style={{
|
|
628
|
+
fontFamily: AppFonts.interMedium,
|
|
629
|
+
fontSize: 11,
|
|
630
|
+
color: AppColors.grayText,
|
|
631
|
+
lineHeight: 14,
|
|
385
632
|
}}>
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
633
|
+
{liveStats}
|
|
634
|
+
</Text>
|
|
635
|
+
</View>
|
|
636
|
+
|
|
637
|
+
{/* Sleek Configure Button */}
|
|
638
|
+
<TouchableScale accessible={true} accessibilityRole="button" accessibilityLabel={`Configure ${moduleItem.label} settings`} onPress={() => {
|
|
639
|
+
animateNextLayout();
|
|
640
|
+
setSettingsPage(moduleItem.key);
|
|
641
|
+
}} style={{
|
|
642
|
+
flexDirection: 'row',
|
|
643
|
+
alignItems: 'center',
|
|
644
|
+
gap: 5,
|
|
645
|
+
backgroundColor: `${AppColors.purple}12`,
|
|
646
|
+
paddingHorizontal: 10,
|
|
647
|
+
paddingVertical: 5,
|
|
648
|
+
borderRadius: 8,
|
|
649
|
+
borderWidth: 1,
|
|
650
|
+
borderColor: `${AppColors.purple}26`,
|
|
651
|
+
}}>
|
|
652
|
+
<SettingsIcon color={AppColors.purple} size={11}/>
|
|
653
|
+
<Text style={{
|
|
654
|
+
fontFamily: AppFonts.interBold,
|
|
655
|
+
fontSize: 11,
|
|
656
|
+
lineHeight: 14,
|
|
657
|
+
color: AppColors.purple,
|
|
658
|
+
}}>
|
|
659
|
+
{t('settings.configure')}
|
|
660
|
+
</Text>
|
|
661
|
+
<ForwardChevronIcon color={AppColors.purple} size={9}/>
|
|
662
|
+
</TouchableScale>
|
|
663
|
+
</View>)}
|
|
664
|
+
</View>);
|
|
392
665
|
})}
|
|
666
|
+
</View>
|
|
393
667
|
</View>) : (
|
|
394
|
-
/* UI Preferences
|
|
395
|
-
<View style={{
|
|
668
|
+
/* UI Preferences Subtab */
|
|
669
|
+
<View style={{ gap: 14 }}>
|
|
670
|
+
{/* Section 1: Appearance */}
|
|
671
|
+
<View style={{
|
|
396
672
|
backgroundColor: AppColors.primaryLight,
|
|
397
|
-
borderRadius:
|
|
673
|
+
borderRadius: 14,
|
|
398
674
|
borderWidth: 1,
|
|
399
675
|
borderColor: AppColors.grayBorderSecondary,
|
|
400
676
|
overflow: 'hidden',
|
|
401
|
-
|
|
402
|
-
<View style={{
|
|
403
|
-
flexDirection: 'row',
|
|
404
|
-
alignItems: 'center',
|
|
405
|
-
paddingVertical: 12,
|
|
406
|
-
paddingHorizontal: 14,
|
|
677
|
+
padding: 14,
|
|
407
678
|
gap: 12,
|
|
408
679
|
}}>
|
|
409
|
-
{
|
|
680
|
+
<Text style={{
|
|
681
|
+
fontFamily: AppFonts.interBold,
|
|
682
|
+
fontSize: 11,
|
|
683
|
+
lineHeight: 14,
|
|
684
|
+
color: AppColors.grayTextWeak,
|
|
685
|
+
letterSpacing: 0.8,
|
|
686
|
+
}}>
|
|
687
|
+
{t('settings.appearanceTheme')}
|
|
688
|
+
</Text>
|
|
689
|
+
|
|
410
690
|
<View style={{
|
|
411
|
-
flex: 1,
|
|
412
691
|
flexDirection: 'row',
|
|
413
692
|
alignItems: 'center',
|
|
414
|
-
|
|
693
|
+
justifyContent: 'space-between',
|
|
415
694
|
}}>
|
|
416
695
|
<View style={{
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
696
|
+
flexDirection: 'row',
|
|
697
|
+
alignItems: 'center',
|
|
698
|
+
gap: 10,
|
|
699
|
+
flex: 1,
|
|
700
|
+
}}>
|
|
701
|
+
<View style={{
|
|
702
|
+
width: 32,
|
|
703
|
+
height: 32,
|
|
704
|
+
borderRadius: 8,
|
|
420
705
|
backgroundColor: AppColors.purpleShade50,
|
|
421
|
-
borderWidth: 1,
|
|
422
|
-
borderColor: `${AppColors.purple}33`,
|
|
423
706
|
alignItems: 'center',
|
|
424
707
|
justifyContent: 'center',
|
|
425
708
|
}}>
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
709
|
+
{isDark ? (<SunIcon color={AppColors.purple} size={15}/>) : (<MoonIcon color={AppColors.purple} size={15}/>)}
|
|
710
|
+
</View>
|
|
711
|
+
<View style={{ flex: 1 }}>
|
|
712
|
+
<Text style={{
|
|
430
713
|
fontFamily: AppFonts.interBold,
|
|
431
|
-
fontSize: 13,
|
|
714
|
+
fontSize: 13.5,
|
|
715
|
+
lineHeight: 18,
|
|
432
716
|
color: AppColors.primaryBlack,
|
|
433
717
|
}}>
|
|
434
|
-
|
|
435
|
-
|
|
718
|
+
{t('settings.general.darkMode')}
|
|
719
|
+
</Text>
|
|
720
|
+
<Text style={{
|
|
721
|
+
fontFamily: AppFonts.interRegular,
|
|
722
|
+
fontSize: 11,
|
|
723
|
+
lineHeight: 15,
|
|
724
|
+
color: AppColors.grayText,
|
|
725
|
+
marginTop: 1,
|
|
726
|
+
}}>
|
|
727
|
+
{t('settings.general.darkModeDescription')}
|
|
728
|
+
</Text>
|
|
729
|
+
</View>
|
|
436
730
|
</View>
|
|
437
|
-
</View>
|
|
438
731
|
|
|
439
|
-
|
|
440
|
-
<TouchableScale onPress={() => {
|
|
732
|
+
<TouchableScale accessible={true} accessibilityRole="switch" accessibilityLabel="Toggle Dark Theme" accessibilityState={{ checked: isDark }} onPress={() => {
|
|
441
733
|
const newTheme = !isDark;
|
|
442
734
|
setIsDark(newTheme);
|
|
443
735
|
toggleGlobalTheme(newTheme);
|
|
444
736
|
}} style={{
|
|
445
|
-
width:
|
|
446
|
-
height:
|
|
447
|
-
borderRadius:
|
|
737
|
+
width: 42,
|
|
738
|
+
height: 24,
|
|
739
|
+
borderRadius: 12,
|
|
448
740
|
backgroundColor: isDark
|
|
449
741
|
? AppColors.purple
|
|
450
742
|
: AppColors.grayBorderSecondary,
|
|
@@ -452,226 +744,243 @@ const SettingsPanel = () => {
|
|
|
452
744
|
justifyContent: 'center',
|
|
453
745
|
alignItems: isDark ? 'flex-end' : 'flex-start',
|
|
454
746
|
}}>
|
|
455
|
-
|
|
456
|
-
width:
|
|
457
|
-
height:
|
|
458
|
-
borderRadius:
|
|
747
|
+
<View style={{
|
|
748
|
+
width: 20,
|
|
749
|
+
height: 20,
|
|
750
|
+
borderRadius: 10,
|
|
459
751
|
backgroundColor: AppColors.white,
|
|
460
752
|
shadowColor: AppColors.black,
|
|
461
|
-
shadowOpacity: 0.
|
|
462
|
-
shadowRadius:
|
|
753
|
+
shadowOpacity: 0.18,
|
|
754
|
+
shadowRadius: 2,
|
|
463
755
|
shadowOffset: { width: 0, height: 1 },
|
|
464
756
|
}}/>
|
|
465
|
-
|
|
757
|
+
</TouchableScale>
|
|
758
|
+
</View>
|
|
466
759
|
</View>
|
|
467
760
|
|
|
468
|
-
{/*
|
|
469
|
-
<View style={{
|
|
470
|
-
height: 1,
|
|
471
|
-
backgroundColor: AppColors.dividerColor,
|
|
472
|
-
}}/>
|
|
473
|
-
|
|
474
|
-
{/* Modal Height */}
|
|
761
|
+
{/* Section 2: Window & Layout */}
|
|
475
762
|
<View style={{
|
|
476
|
-
|
|
477
|
-
|
|
763
|
+
backgroundColor: AppColors.primaryLight,
|
|
764
|
+
borderRadius: 14,
|
|
765
|
+
borderWidth: 1,
|
|
766
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
767
|
+
overflow: 'hidden',
|
|
768
|
+
padding: 14,
|
|
769
|
+
gap: 14,
|
|
478
770
|
}}>
|
|
479
|
-
<
|
|
771
|
+
<Text style={{
|
|
772
|
+
fontFamily: AppFonts.interBold,
|
|
773
|
+
fontSize: 11,
|
|
774
|
+
lineHeight: 14,
|
|
775
|
+
color: AppColors.grayTextWeak,
|
|
776
|
+
letterSpacing: 0.8,
|
|
777
|
+
}}>
|
|
778
|
+
{t('settings.windowLayout')}
|
|
779
|
+
</Text>
|
|
780
|
+
|
|
781
|
+
{/* Modal Height */}
|
|
782
|
+
<View style={{ gap: 8 }}>
|
|
783
|
+
<View style={{
|
|
480
784
|
flexDirection: 'row',
|
|
481
785
|
alignItems: 'center',
|
|
482
|
-
gap:
|
|
786
|
+
gap: 10,
|
|
483
787
|
}}>
|
|
484
|
-
|
|
485
|
-
width:
|
|
486
|
-
height:
|
|
487
|
-
borderRadius:
|
|
788
|
+
<View style={{
|
|
789
|
+
width: 32,
|
|
790
|
+
height: 32,
|
|
791
|
+
borderRadius: 8,
|
|
488
792
|
backgroundColor: AppColors.purpleShade50,
|
|
489
|
-
borderWidth: 1,
|
|
490
|
-
borderColor: `${AppColors.purple}33`,
|
|
491
793
|
alignItems: 'center',
|
|
492
794
|
justifyContent: 'center',
|
|
493
795
|
}}>
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
796
|
+
<ScreenIcon color={AppColors.purple} size={15}/>
|
|
797
|
+
</View>
|
|
798
|
+
<View style={{ flex: 1 }}>
|
|
799
|
+
<Text style={{
|
|
498
800
|
fontFamily: AppFonts.interBold,
|
|
499
|
-
fontSize: 13,
|
|
801
|
+
fontSize: 13.5,
|
|
802
|
+
lineHeight: 18,
|
|
500
803
|
color: AppColors.primaryBlack,
|
|
501
804
|
}}>
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
805
|
+
{t('settings.general.modalHeight')}
|
|
806
|
+
</Text>
|
|
807
|
+
<Text style={{
|
|
505
808
|
fontFamily: AppFonts.interRegular,
|
|
506
809
|
fontSize: 11,
|
|
810
|
+
lineHeight: 15,
|
|
507
811
|
color: AppColors.grayText,
|
|
508
812
|
marginTop: 1,
|
|
509
813
|
}}>
|
|
510
|
-
|
|
511
|
-
|
|
814
|
+
{t('settings.general.modalHeightDescription')}
|
|
815
|
+
</Text>
|
|
816
|
+
</View>
|
|
512
817
|
</View>
|
|
513
|
-
</View>
|
|
514
818
|
|
|
515
|
-
|
|
516
|
-
<View style={{
|
|
819
|
+
<View style={{
|
|
517
820
|
flexDirection: 'row',
|
|
518
821
|
backgroundColor: AppColors.grayBackground,
|
|
519
|
-
borderRadius:
|
|
520
|
-
padding:
|
|
521
|
-
marginTop: 10,
|
|
822
|
+
borderRadius: 10,
|
|
823
|
+
padding: 3,
|
|
522
824
|
borderWidth: 1,
|
|
523
825
|
borderColor: AppColors.dividerColor,
|
|
524
826
|
}}>
|
|
525
|
-
|
|
827
|
+
{[50, 70, 90, 100].map(opt => {
|
|
526
828
|
const isActive = modalHeightPercent === opt;
|
|
527
|
-
return (<TouchableScale key={opt} onPress={() => setModalHeightPercent(opt)} style={{
|
|
829
|
+
return (<TouchableScale key={opt} accessible={true} accessibilityRole="button" accessibilityLabel={`Set window height to ${opt} percent`} accessibilityState={{ selected: isActive }} onPress={() => setModalHeightPercent(opt)} style={{
|
|
528
830
|
flex: 1,
|
|
529
|
-
paddingVertical:
|
|
831
|
+
paddingVertical: 7,
|
|
530
832
|
alignItems: 'center',
|
|
531
|
-
borderRadius:
|
|
833
|
+
borderRadius: 8,
|
|
532
834
|
backgroundColor: isActive
|
|
533
835
|
? AppColors.purple
|
|
534
836
|
: 'transparent',
|
|
535
837
|
}}>
|
|
536
|
-
|
|
838
|
+
<Text style={{
|
|
537
839
|
fontFamily: AppFonts.interBold,
|
|
538
|
-
fontSize: 11,
|
|
539
|
-
|
|
840
|
+
fontSize: 11.5,
|
|
841
|
+
lineHeight: 15,
|
|
842
|
+
color: isActive
|
|
843
|
+
? AppColors.white
|
|
844
|
+
: AppColors.grayText,
|
|
540
845
|
}}>
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
846
|
+
{opt}%
|
|
847
|
+
</Text>
|
|
848
|
+
</TouchableScale>);
|
|
544
849
|
})}
|
|
850
|
+
</View>
|
|
545
851
|
</View>
|
|
546
|
-
</View>
|
|
547
852
|
|
|
548
|
-
|
|
549
|
-
<View style={{
|
|
550
|
-
height: 1,
|
|
551
|
-
backgroundColor: AppColors.dividerColor,
|
|
552
|
-
}}/>
|
|
853
|
+
<View style={{ height: 1, backgroundColor: AppColors.dividerColor }}/>
|
|
553
854
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
paddingHorizontal: 14,
|
|
558
|
-
}}>
|
|
559
|
-
<View style={{
|
|
855
|
+
{/* Modal Animation */}
|
|
856
|
+
<View style={{ gap: 8 }}>
|
|
857
|
+
<View style={{
|
|
560
858
|
flexDirection: 'row',
|
|
561
859
|
alignItems: 'center',
|
|
562
|
-
gap:
|
|
860
|
+
gap: 10,
|
|
563
861
|
}}>
|
|
564
|
-
|
|
565
|
-
width:
|
|
566
|
-
height:
|
|
567
|
-
borderRadius:
|
|
862
|
+
<View style={{
|
|
863
|
+
width: 32,
|
|
864
|
+
height: 32,
|
|
865
|
+
borderRadius: 8,
|
|
568
866
|
backgroundColor: AppColors.purpleShade50,
|
|
569
|
-
borderWidth: 1,
|
|
570
|
-
borderColor: `${AppColors.purple}33`,
|
|
571
867
|
alignItems: 'center',
|
|
572
868
|
justifyContent: 'center',
|
|
573
869
|
}}>
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
870
|
+
<MotionIcon color={AppColors.purple} size={15}/>
|
|
871
|
+
</View>
|
|
872
|
+
<View style={{ flex: 1 }}>
|
|
873
|
+
<Text style={{
|
|
578
874
|
fontFamily: AppFonts.interBold,
|
|
579
|
-
fontSize: 13,
|
|
875
|
+
fontSize: 13.5,
|
|
876
|
+
lineHeight: 18,
|
|
580
877
|
color: AppColors.primaryBlack,
|
|
581
878
|
}}>
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
879
|
+
{t('settings.general.modalAnimation')}
|
|
880
|
+
</Text>
|
|
881
|
+
<Text style={{
|
|
585
882
|
fontFamily: AppFonts.interRegular,
|
|
586
883
|
fontSize: 11,
|
|
884
|
+
lineHeight: 15,
|
|
587
885
|
color: AppColors.grayText,
|
|
588
886
|
marginTop: 1,
|
|
589
887
|
}}>
|
|
590
|
-
|
|
591
|
-
|
|
888
|
+
{t('settings.general.modalAnimationDescription')}
|
|
889
|
+
</Text>
|
|
890
|
+
</View>
|
|
592
891
|
</View>
|
|
593
|
-
</View>
|
|
594
892
|
|
|
595
|
-
|
|
596
|
-
<View style={{
|
|
893
|
+
<View style={{
|
|
597
894
|
flexDirection: 'row',
|
|
598
895
|
backgroundColor: AppColors.grayBackground,
|
|
599
|
-
borderRadius:
|
|
600
|
-
padding:
|
|
601
|
-
marginTop: 10,
|
|
896
|
+
borderRadius: 10,
|
|
897
|
+
padding: 3,
|
|
602
898
|
borderWidth: 1,
|
|
603
899
|
borderColor: AppColors.dividerColor,
|
|
604
900
|
}}>
|
|
605
|
-
|
|
901
|
+
{[
|
|
606
902
|
{ key: 'slide', label: 'Slide Up' },
|
|
607
903
|
{ key: 'fade', label: 'Fade' },
|
|
608
904
|
{ key: 'none', label: 'None' },
|
|
609
|
-
]
|
|
905
|
+
].map(opt => {
|
|
610
906
|
const isActive = modalAnimationType === opt.key;
|
|
611
|
-
return (<TouchableScale key={opt.key} onPress={() => setModalAnimationType(opt.key)} style={{
|
|
907
|
+
return (<TouchableScale key={opt.key} accessible={true} accessibilityRole="button" accessibilityLabel={`Set transition animation to ${opt.label}`} accessibilityState={{ selected: isActive }} onPress={() => setModalAnimationType(opt.key)} style={{
|
|
612
908
|
flex: 1,
|
|
613
|
-
paddingVertical:
|
|
909
|
+
paddingVertical: 7,
|
|
614
910
|
alignItems: 'center',
|
|
615
|
-
borderRadius:
|
|
911
|
+
borderRadius: 8,
|
|
616
912
|
backgroundColor: isActive
|
|
617
913
|
? AppColors.purple
|
|
618
914
|
: 'transparent',
|
|
619
915
|
}}>
|
|
620
|
-
|
|
916
|
+
<Text style={{
|
|
621
917
|
fontFamily: AppFonts.interBold,
|
|
622
|
-
fontSize: 11,
|
|
623
|
-
|
|
918
|
+
fontSize: 11.5,
|
|
919
|
+
lineHeight: 15,
|
|
920
|
+
color: isActive
|
|
921
|
+
? AppColors.white
|
|
922
|
+
: AppColors.grayText,
|
|
624
923
|
}}>
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
924
|
+
{opt.label}
|
|
925
|
+
</Text>
|
|
926
|
+
</TouchableScale>);
|
|
628
927
|
})}
|
|
928
|
+
</View>
|
|
629
929
|
</View>
|
|
630
930
|
</View>
|
|
631
931
|
|
|
632
|
-
{/*
|
|
932
|
+
{/* Section 3: Default Startup Tab */}
|
|
633
933
|
<View style={{
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
934
|
+
backgroundColor: AppColors.primaryLight,
|
|
935
|
+
borderRadius: 14,
|
|
936
|
+
borderWidth: 1,
|
|
937
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
938
|
+
overflow: 'hidden',
|
|
939
|
+
padding: 14,
|
|
940
|
+
gap: 12,
|
|
941
|
+
}}>
|
|
942
|
+
<Text style={{
|
|
943
|
+
fontFamily: AppFonts.interBold,
|
|
944
|
+
fontSize: 11,
|
|
945
|
+
lineHeight: 14,
|
|
946
|
+
color: AppColors.grayTextWeak,
|
|
947
|
+
letterSpacing: 0.8,
|
|
642
948
|
}}>
|
|
949
|
+
{t('settings.startupDefault')}
|
|
950
|
+
</Text>
|
|
951
|
+
|
|
643
952
|
<View style={{
|
|
644
953
|
flexDirection: 'row',
|
|
645
954
|
alignItems: 'center',
|
|
646
|
-
gap:
|
|
955
|
+
gap: 10,
|
|
647
956
|
}}>
|
|
648
957
|
<View style={{
|
|
649
|
-
width:
|
|
650
|
-
height:
|
|
651
|
-
borderRadius:
|
|
958
|
+
width: 32,
|
|
959
|
+
height: 32,
|
|
960
|
+
borderRadius: 8,
|
|
652
961
|
backgroundColor: AppColors.purpleShade50,
|
|
653
|
-
borderWidth: 1,
|
|
654
|
-
borderColor: `${AppColors.purple}33`,
|
|
655
962
|
alignItems: 'center',
|
|
656
963
|
justifyContent: 'center',
|
|
657
964
|
}}>
|
|
658
|
-
<LayersIcon color={AppColors.purple} size={
|
|
965
|
+
<LayersIcon color={AppColors.purple} size={15}/>
|
|
659
966
|
</View>
|
|
660
967
|
<View style={{ flex: 1 }}>
|
|
661
968
|
<Text style={{
|
|
662
969
|
fontFamily: AppFonts.interBold,
|
|
663
|
-
fontSize: 13,
|
|
970
|
+
fontSize: 13.5,
|
|
971
|
+
lineHeight: 18,
|
|
664
972
|
color: AppColors.primaryBlack,
|
|
665
973
|
}}>
|
|
666
|
-
|
|
974
|
+
{t('settings.general.defaultOpeningTab')}
|
|
667
975
|
</Text>
|
|
668
976
|
<Text style={{
|
|
669
977
|
fontFamily: AppFonts.interRegular,
|
|
670
978
|
fontSize: 11,
|
|
979
|
+
lineHeight: 15,
|
|
671
980
|
color: AppColors.grayText,
|
|
672
981
|
marginTop: 1,
|
|
673
982
|
}}>
|
|
674
|
-
|
|
983
|
+
{t('settings.general.defaultOpeningTabDesc')}
|
|
675
984
|
</Text>
|
|
676
985
|
</View>
|
|
677
986
|
</View>
|
|
@@ -681,13 +990,15 @@ const SettingsPanel = () => {
|
|
|
681
990
|
flexDirection: 'row',
|
|
682
991
|
flexWrap: 'wrap',
|
|
683
992
|
gap: 8,
|
|
684
|
-
marginTop:
|
|
993
|
+
marginTop: 4,
|
|
685
994
|
}}>
|
|
686
|
-
{
|
|
687
|
-
.filter(tab => tab.key === 'apis' ||
|
|
995
|
+
{allModules
|
|
996
|
+
.filter(tab => tab.key === 'apis' ||
|
|
997
|
+
stagedTabVisibility?.[tab.key] ||
|
|
998
|
+
tabVisibility?.[tab.key])
|
|
688
999
|
.map(tab => {
|
|
689
1000
|
const isActive = defaultTab === tab.key;
|
|
690
|
-
return (<TouchableScale key={tab.key} onPress={() => setDefaultTab(tab.key)} style={{
|
|
1001
|
+
return (<TouchableScale key={tab.key} accessible={true} accessibilityRole="button" accessibilityLabel={`Set ${tab.label} as default tab`} accessibilityState={{ selected: isActive }} onPress={() => setDefaultTab(tab.key)} style={{
|
|
691
1002
|
flexDirection: 'row',
|
|
692
1003
|
alignItems: 'center',
|
|
693
1004
|
gap: 8,
|
|
@@ -695,186 +1006,190 @@ const SettingsPanel = () => {
|
|
|
695
1006
|
paddingHorizontal: 12,
|
|
696
1007
|
borderRadius: 10,
|
|
697
1008
|
borderWidth: 1.5,
|
|
698
|
-
borderColor: isActive
|
|
699
|
-
|
|
1009
|
+
borderColor: isActive
|
|
1010
|
+
? AppColors.purple
|
|
1011
|
+
: AppColors.grayBorderSecondary,
|
|
1012
|
+
backgroundColor: isActive
|
|
1013
|
+
? `${AppColors.purple}0F`
|
|
1014
|
+
: AppColors.primaryLight,
|
|
700
1015
|
minWidth: '47%',
|
|
701
1016
|
flex: 1,
|
|
702
1017
|
}}>
|
|
703
|
-
<View style={{
|
|
704
|
-
width: 22,
|
|
705
|
-
height: 22,
|
|
706
|
-
borderRadius: 6,
|
|
707
|
-
backgroundColor: isActive ? AppColors.purple : AppColors.purpleShade50,
|
|
708
|
-
alignItems: 'center',
|
|
709
|
-
justifyContent: 'center',
|
|
710
|
-
}}>
|
|
711
|
-
{tab.icon === 'apis' && (<SignalIcon color={isActive ? AppColors.white : AppColors.purple} size={11}/>)}
|
|
712
|
-
{tab.icon === 'logs' && (<TerminalIcon color={isActive ? AppColors.white : AppColors.purple} size={11}/>)}
|
|
713
|
-
{tab.icon === 'analytics' && (<AnalyticsIcon color={isActive ? AppColors.white : AppColors.purple} size={11}/>)}
|
|
714
|
-
{tab.icon === 'redux' && (<ReduxIcon color={isActive ? AppColors.white : AppColors.purple} size={11}/>)}
|
|
715
|
-
{tab.icon === 'bundle' && (<PackageIcon color={isActive ? AppColors.white : AppColors.purple} size={11}/>)}
|
|
716
|
-
{tab.icon === 'performance' && (<PerformanceIcon color={isActive ? AppColors.white : AppColors.purple} size={11}/>)}
|
|
717
|
-
{tab.icon === 'crash' && (<CrashIcon color={isActive ? AppColors.white : AppColors.purple} size={11}/>)}
|
|
718
|
-
</View>
|
|
719
1018
|
<Text style={{
|
|
720
1019
|
fontFamily: AppFonts.interBold,
|
|
721
|
-
fontSize:
|
|
722
|
-
|
|
1020
|
+
fontSize: 12.5,
|
|
1021
|
+
lineHeight: 16,
|
|
1022
|
+
color: isActive
|
|
1023
|
+
? AppColors.purple
|
|
1024
|
+
: AppColors.primaryBlack,
|
|
723
1025
|
flex: 1,
|
|
724
1026
|
}}>
|
|
725
|
-
|
|
1027
|
+
{tab.label}
|
|
726
1028
|
</Text>
|
|
727
1029
|
{isActive && (<View style={{
|
|
728
|
-
width:
|
|
729
|
-
height:
|
|
730
|
-
borderRadius:
|
|
1030
|
+
width: 16,
|
|
1031
|
+
height: 16,
|
|
1032
|
+
borderRadius: 8,
|
|
731
1033
|
backgroundColor: AppColors.purple,
|
|
732
1034
|
alignItems: 'center',
|
|
733
1035
|
justifyContent: 'center',
|
|
734
1036
|
}}>
|
|
735
|
-
<CheckIcon size={
|
|
1037
|
+
<CheckIcon size={9} color={AppColors.white}/>
|
|
736
1038
|
</View>)}
|
|
737
1039
|
</TouchableScale>);
|
|
738
1040
|
})}
|
|
739
1041
|
</View>
|
|
740
1042
|
</View>
|
|
741
1043
|
|
|
742
|
-
{/*
|
|
1044
|
+
{/* Section 4: Log Deduplication & Levels */}
|
|
743
1045
|
<View style={{
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
1046
|
+
backgroundColor: AppColors.primaryLight,
|
|
1047
|
+
borderRadius: 14,
|
|
1048
|
+
borderWidth: 1,
|
|
1049
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
1050
|
+
overflow: 'hidden',
|
|
1051
|
+
padding: 14,
|
|
1052
|
+
gap: 14,
|
|
1053
|
+
}}>
|
|
1054
|
+
<Text style={{
|
|
1055
|
+
fontFamily: AppFonts.interBold,
|
|
1056
|
+
fontSize: 11,
|
|
1057
|
+
lineHeight: 14,
|
|
1058
|
+
color: AppColors.grayTextWeak,
|
|
1059
|
+
letterSpacing: 0.8,
|
|
1060
|
+
}}>
|
|
1061
|
+
{t('settings.logFiltersDeduplication')}
|
|
1062
|
+
</Text>
|
|
747
1063
|
|
|
748
|
-
|
|
749
|
-
|
|
1064
|
+
{/* Show Duplicate Logs */}
|
|
1065
|
+
<View style={{
|
|
750
1066
|
flexDirection: 'row',
|
|
751
1067
|
alignItems: 'center',
|
|
752
|
-
|
|
753
|
-
paddingHorizontal: 14,
|
|
754
|
-
gap: 12,
|
|
1068
|
+
justifyContent: 'space-between',
|
|
755
1069
|
}}>
|
|
756
|
-
|
|
757
|
-
flex: 1,
|
|
1070
|
+
<View style={{
|
|
758
1071
|
flexDirection: 'row',
|
|
759
1072
|
alignItems: 'center',
|
|
760
|
-
gap:
|
|
1073
|
+
gap: 10,
|
|
1074
|
+
flex: 1,
|
|
761
1075
|
}}>
|
|
762
|
-
|
|
763
|
-
width:
|
|
764
|
-
height:
|
|
765
|
-
borderRadius:
|
|
1076
|
+
<View style={{
|
|
1077
|
+
width: 32,
|
|
1078
|
+
height: 32,
|
|
1079
|
+
borderRadius: 8,
|
|
766
1080
|
backgroundColor: AppColors.purpleShade50,
|
|
767
|
-
borderWidth: 1,
|
|
768
|
-
borderColor: `${AppColors.purple}33`,
|
|
769
1081
|
alignItems: 'center',
|
|
770
1082
|
justifyContent: 'center',
|
|
771
1083
|
}}>
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
1084
|
+
<EyeIcon color={AppColors.purple} size={15}/>
|
|
1085
|
+
</View>
|
|
1086
|
+
<View style={{ flex: 1 }}>
|
|
1087
|
+
<Text style={{
|
|
776
1088
|
fontFamily: AppFonts.interBold,
|
|
777
|
-
fontSize: 13,
|
|
1089
|
+
fontSize: 13.5,
|
|
1090
|
+
lineHeight: 18,
|
|
778
1091
|
color: AppColors.primaryBlack,
|
|
779
1092
|
}}>
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
1093
|
+
{t('settings.general.duplicateLogs')}
|
|
1094
|
+
</Text>
|
|
1095
|
+
<Text style={{
|
|
783
1096
|
fontFamily: AppFonts.interRegular,
|
|
784
1097
|
fontSize: 11,
|
|
1098
|
+
lineHeight: 15,
|
|
785
1099
|
color: AppColors.grayText,
|
|
786
1100
|
marginTop: 1,
|
|
787
1101
|
}}>
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
</
|
|
1102
|
+
{t('settings.general.duplicateLogsDescription')}
|
|
1103
|
+
</Text>
|
|
1104
|
+
</View>
|
|
791
1105
|
</View>
|
|
792
|
-
</View>
|
|
793
1106
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
borderRadius: 11,
|
|
1107
|
+
<TouchableScale accessible={true} accessibilityRole="switch" accessibilityLabel="Toggle show duplicate logs" accessibilityState={{ checked: showDuplicateLogs }} onPress={() => setShowDuplicateLogs(prev => !prev)} style={{
|
|
1108
|
+
width: 42,
|
|
1109
|
+
height: 24,
|
|
1110
|
+
borderRadius: 12,
|
|
799
1111
|
backgroundColor: showDuplicateLogs
|
|
800
1112
|
? AppColors.purple
|
|
801
1113
|
: AppColors.grayBorderSecondary,
|
|
802
1114
|
padding: 2,
|
|
803
1115
|
justifyContent: 'center',
|
|
804
|
-
alignItems: showDuplicateLogs
|
|
1116
|
+
alignItems: showDuplicateLogs
|
|
1117
|
+
? 'flex-end'
|
|
1118
|
+
: 'flex-start',
|
|
805
1119
|
}}>
|
|
806
|
-
|
|
807
|
-
width:
|
|
808
|
-
height:
|
|
809
|
-
borderRadius:
|
|
1120
|
+
<View style={{
|
|
1121
|
+
width: 20,
|
|
1122
|
+
height: 20,
|
|
1123
|
+
borderRadius: 10,
|
|
810
1124
|
backgroundColor: AppColors.white,
|
|
811
1125
|
shadowColor: AppColors.black,
|
|
812
|
-
shadowOpacity: 0.
|
|
813
|
-
shadowRadius:
|
|
1126
|
+
shadowOpacity: 0.18,
|
|
1127
|
+
shadowRadius: 2,
|
|
814
1128
|
shadowOffset: { width: 0, height: 1 },
|
|
815
1129
|
}}/>
|
|
816
|
-
|
|
817
|
-
|
|
1130
|
+
</TouchableScale>
|
|
1131
|
+
</View>
|
|
818
1132
|
|
|
819
|
-
|
|
820
|
-
<View style={{
|
|
821
|
-
height: 1,
|
|
822
|
-
backgroundColor: AppColors.dividerColor,
|
|
823
|
-
}}/>
|
|
1133
|
+
<View style={{ height: 1, backgroundColor: AppColors.dividerColor }}/>
|
|
824
1134
|
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
paddingHorizontal: 14,
|
|
829
|
-
}}>
|
|
830
|
-
<View style={{
|
|
1135
|
+
{/* Console Log Levels */}
|
|
1136
|
+
<View style={{ gap: 8 }}>
|
|
1137
|
+
<View style={{
|
|
831
1138
|
flexDirection: 'row',
|
|
832
1139
|
alignItems: 'center',
|
|
833
|
-
gap:
|
|
1140
|
+
gap: 10,
|
|
834
1141
|
}}>
|
|
835
|
-
|
|
836
|
-
width:
|
|
837
|
-
height:
|
|
838
|
-
borderRadius:
|
|
1142
|
+
<View style={{
|
|
1143
|
+
width: 32,
|
|
1144
|
+
height: 32,
|
|
1145
|
+
borderRadius: 8,
|
|
839
1146
|
backgroundColor: AppColors.purpleShade50,
|
|
840
|
-
borderWidth: 1,
|
|
841
|
-
borderColor: `${AppColors.purple}33`,
|
|
842
1147
|
alignItems: 'center',
|
|
843
1148
|
justifyContent: 'center',
|
|
844
1149
|
}}>
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
1150
|
+
<TerminalIcon color={AppColors.purple} size={15}/>
|
|
1151
|
+
</View>
|
|
1152
|
+
<View style={{ flex: 1 }}>
|
|
1153
|
+
<Text style={{
|
|
849
1154
|
fontFamily: AppFonts.interBold,
|
|
850
|
-
fontSize: 13,
|
|
1155
|
+
fontSize: 13.5,
|
|
1156
|
+
lineHeight: 18,
|
|
851
1157
|
color: AppColors.primaryBlack,
|
|
852
1158
|
}}>
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
1159
|
+
{t('settings.general.activeConsoleLogLevels')}
|
|
1160
|
+
</Text>
|
|
1161
|
+
<Text style={{
|
|
856
1162
|
fontFamily: AppFonts.interRegular,
|
|
857
1163
|
fontSize: 11,
|
|
1164
|
+
lineHeight: 15,
|
|
858
1165
|
color: AppColors.grayText,
|
|
859
1166
|
marginTop: 1,
|
|
860
1167
|
}}>
|
|
861
|
-
|
|
862
|
-
|
|
1168
|
+
{t('settings.general.activeConsoleLogLevelsDesc')}
|
|
1169
|
+
</Text>
|
|
1170
|
+
</View>
|
|
863
1171
|
</View>
|
|
864
|
-
</View>
|
|
865
1172
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
{
|
|
874
|
-
|
|
875
|
-
|
|
1173
|
+
<View style={{ flexDirection: 'row', gap: 8, marginTop: 4 }}>
|
|
1174
|
+
{[
|
|
1175
|
+
{
|
|
1176
|
+
key: 'info',
|
|
1177
|
+
label: 'Info',
|
|
1178
|
+
color: AppColors.blue500,
|
|
1179
|
+
},
|
|
1180
|
+
{
|
|
1181
|
+
key: 'warn',
|
|
1182
|
+
label: 'Warning',
|
|
1183
|
+
color: AppColors.amber500,
|
|
1184
|
+
},
|
|
1185
|
+
{
|
|
1186
|
+
key: 'error',
|
|
1187
|
+
label: 'Error',
|
|
1188
|
+
color: AppColors.errorColor,
|
|
1189
|
+
},
|
|
1190
|
+
].map(level => {
|
|
876
1191
|
const isActive = showConsoleLevels[level.key];
|
|
877
|
-
return (<TouchableScale key={level.key} onPress={() => setShowConsoleLevels(prev => ({
|
|
1192
|
+
return (<TouchableScale key={level.key} accessible={true} accessibilityRole="checkbox" accessibilityLabel={`Toggle ${level.label} logs`} accessibilityState={{ checked: isActive }} onPress={() => setShowConsoleLevels(prev => ({
|
|
878
1193
|
...prev,
|
|
879
1194
|
[level.key]: !prev[level.key],
|
|
880
1195
|
}))} style={{
|
|
@@ -884,112 +1199,113 @@ const SettingsPanel = () => {
|
|
|
884
1199
|
justifyContent: 'center',
|
|
885
1200
|
gap: 6,
|
|
886
1201
|
paddingVertical: 8,
|
|
887
|
-
borderRadius:
|
|
1202
|
+
borderRadius: 9,
|
|
888
1203
|
borderWidth: 1.5,
|
|
889
|
-
borderColor: isActive
|
|
890
|
-
|
|
1204
|
+
borderColor: isActive
|
|
1205
|
+
? level.color
|
|
1206
|
+
: AppColors.grayBorderSecondary,
|
|
1207
|
+
backgroundColor: isActive
|
|
1208
|
+
? `${level.color}0D`
|
|
1209
|
+
: AppColors.primaryLight,
|
|
891
1210
|
}}>
|
|
892
|
-
|
|
1211
|
+
<View style={{
|
|
893
1212
|
width: 8,
|
|
894
1213
|
height: 8,
|
|
895
1214
|
borderRadius: 4,
|
|
896
|
-
backgroundColor: isActive
|
|
1215
|
+
backgroundColor: isActive
|
|
1216
|
+
? level.color
|
|
1217
|
+
: AppColors.grayBorderSecondary,
|
|
897
1218
|
}}/>
|
|
898
|
-
|
|
1219
|
+
<Text style={{
|
|
899
1220
|
fontFamily: AppFonts.interBold,
|
|
900
|
-
fontSize: 11,
|
|
901
|
-
|
|
1221
|
+
fontSize: 11.5,
|
|
1222
|
+
lineHeight: 15,
|
|
1223
|
+
color: isActive
|
|
1224
|
+
? level.color
|
|
1225
|
+
: AppColors.grayText,
|
|
902
1226
|
}}>
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
1227
|
+
{level.label}
|
|
1228
|
+
</Text>
|
|
1229
|
+
</TouchableScale>);
|
|
906
1230
|
})}
|
|
1231
|
+
</View>
|
|
907
1232
|
</View>
|
|
908
1233
|
</View>
|
|
909
1234
|
|
|
910
|
-
{/*
|
|
911
|
-
<View style={{
|
|
912
|
-
height: 1,
|
|
913
|
-
backgroundColor: AppColors.dividerColor,
|
|
914
|
-
}}/>
|
|
915
|
-
|
|
916
|
-
{/* Reset Settings */}
|
|
1235
|
+
{/* Section 5: Reset Settings */}
|
|
917
1236
|
<View style={{
|
|
1237
|
+
backgroundColor: AppColors.primaryLight,
|
|
1238
|
+
borderRadius: 14,
|
|
1239
|
+
borderWidth: 1,
|
|
1240
|
+
borderColor: `${AppColors.errorColor}33`,
|
|
1241
|
+
overflow: 'hidden',
|
|
1242
|
+
padding: 14,
|
|
918
1243
|
flexDirection: 'row',
|
|
919
1244
|
alignItems: 'center',
|
|
920
|
-
paddingVertical: 12,
|
|
921
|
-
paddingHorizontal: 14,
|
|
922
1245
|
gap: 12,
|
|
923
1246
|
}}>
|
|
924
1247
|
<View style={{
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
gap: 8,
|
|
929
|
-
}}>
|
|
930
|
-
<View style={{
|
|
931
|
-
width: 20,
|
|
932
|
-
height: 20,
|
|
933
|
-
borderRadius: 6,
|
|
1248
|
+
width: 34,
|
|
1249
|
+
height: 34,
|
|
1250
|
+
borderRadius: 9,
|
|
934
1251
|
backgroundColor: `${AppColors.errorColor}14`,
|
|
935
|
-
borderWidth: 1,
|
|
936
|
-
borderColor: `${AppColors.errorColor}33`,
|
|
937
1252
|
alignItems: 'center',
|
|
938
1253
|
justifyContent: 'center',
|
|
939
1254
|
}}>
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
1255
|
+
<TrashIcon color={AppColors.errorColor} size={15}/>
|
|
1256
|
+
</View>
|
|
1257
|
+
<View style={{ flex: 1 }}>
|
|
1258
|
+
<Text style={{
|
|
944
1259
|
fontFamily: AppFonts.interBold,
|
|
945
|
-
fontSize: 13,
|
|
1260
|
+
fontSize: 13.5,
|
|
1261
|
+
lineHeight: 18,
|
|
946
1262
|
color: AppColors.primaryBlack,
|
|
947
1263
|
}}>
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
1264
|
+
{t('settings.resetSettings')}
|
|
1265
|
+
</Text>
|
|
1266
|
+
<Text style={{
|
|
951
1267
|
fontFamily: AppFonts.interRegular,
|
|
952
1268
|
fontSize: 11,
|
|
1269
|
+
lineHeight: 15,
|
|
953
1270
|
color: AppColors.grayText,
|
|
954
1271
|
marginTop: 1,
|
|
955
1272
|
}}>
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
</View>
|
|
1273
|
+
{t('settings.resetSettingsDesc')}
|
|
1274
|
+
</Text>
|
|
959
1275
|
</View>
|
|
960
1276
|
|
|
961
|
-
<TouchableScale onPress={resetToDefaults} style={{
|
|
962
|
-
paddingHorizontal:
|
|
963
|
-
paddingVertical:
|
|
964
|
-
borderRadius:
|
|
1277
|
+
<TouchableScale accessible={true} accessibilityRole="button" accessibilityLabel="Reset all settings to default" onPress={resetToDefaults} style={{
|
|
1278
|
+
paddingHorizontal: 12,
|
|
1279
|
+
paddingVertical: 7,
|
|
1280
|
+
borderRadius: 8,
|
|
965
1281
|
backgroundColor: `${AppColors.errorColor}14`,
|
|
966
1282
|
borderWidth: 1,
|
|
967
|
-
borderColor: `${AppColors.errorColor}
|
|
1283
|
+
borderColor: `${AppColors.errorColor}38`,
|
|
968
1284
|
}}>
|
|
969
1285
|
<Text style={{
|
|
970
1286
|
fontFamily: AppFonts.interBold,
|
|
971
|
-
fontSize: 11,
|
|
1287
|
+
fontSize: 11.5,
|
|
1288
|
+
lineHeight: 15,
|
|
972
1289
|
color: AppColors.errorColor,
|
|
973
1290
|
}}>
|
|
974
|
-
|
|
1291
|
+
{t('settings.reset')}
|
|
975
1292
|
</Text>
|
|
976
1293
|
</TouchableScale>
|
|
977
1294
|
</View>
|
|
978
1295
|
</View>)}
|
|
979
1296
|
|
|
980
|
-
|
|
981
|
-
{/* Storage Status */}
|
|
1297
|
+
{/* Storage & Engine Status Card */}
|
|
982
1298
|
<View style={{
|
|
983
|
-
backgroundColor:
|
|
984
|
-
? `${AppColors.liveGreen}
|
|
985
|
-
: `${AppColors.amber600}
|
|
1299
|
+
backgroundColor: isPersistent
|
|
1300
|
+
? `${AppColors.liveGreen}12`
|
|
1301
|
+
: `${AppColors.amber600}12`,
|
|
986
1302
|
borderRadius: 12,
|
|
987
1303
|
borderWidth: 1,
|
|
988
|
-
borderColor:
|
|
1304
|
+
borderColor: isPersistent
|
|
989
1305
|
? `${AppColors.liveGreen}33`
|
|
990
1306
|
: `${AppColors.amber600}33`,
|
|
991
1307
|
padding: 12,
|
|
992
|
-
|
|
1308
|
+
marginBottom: 10,
|
|
993
1309
|
flexDirection: 'row',
|
|
994
1310
|
alignItems: 'center',
|
|
995
1311
|
gap: 10,
|
|
@@ -998,32 +1314,106 @@ const SettingsPanel = () => {
|
|
|
998
1314
|
width: 8,
|
|
999
1315
|
height: 8,
|
|
1000
1316
|
borderRadius: 4,
|
|
1001
|
-
backgroundColor:
|
|
1317
|
+
backgroundColor: isPersistent
|
|
1318
|
+
? AppColors.green500
|
|
1319
|
+
: AppColors.amber600,
|
|
1002
1320
|
}}/>
|
|
1003
1321
|
<View style={{ flex: 1 }}>
|
|
1004
1322
|
<Text style={{
|
|
1005
1323
|
fontFamily: AppFonts.interBold,
|
|
1006
1324
|
fontSize: 12,
|
|
1007
|
-
|
|
1325
|
+
lineHeight: 16,
|
|
1326
|
+
color: isPersistent
|
|
1327
|
+
? AppColors.green700
|
|
1328
|
+
: AppColors.amber800,
|
|
1008
1329
|
}}>
|
|
1009
|
-
{
|
|
1010
|
-
?
|
|
1011
|
-
|
|
1330
|
+
{isPersistent
|
|
1331
|
+
? t('settings.general.storageStatusEnabled', {
|
|
1332
|
+
type: storage ? 'Custom Storage' : 'iOS NSUserDefaults',
|
|
1333
|
+
})
|
|
1334
|
+
: t('settings.general.storageStatusDisabled')}
|
|
1012
1335
|
</Text>
|
|
1013
1336
|
<Text style={{
|
|
1014
1337
|
fontFamily: AppFonts.interRegular,
|
|
1015
1338
|
fontSize: 10.5,
|
|
1016
|
-
|
|
1339
|
+
lineHeight: 14,
|
|
1340
|
+
color: isPersistent
|
|
1341
|
+
? AppColors.green800
|
|
1342
|
+
: AppColors.amber800,
|
|
1017
1343
|
marginTop: 2,
|
|
1018
|
-
opacity: 0.
|
|
1344
|
+
opacity: 0.85,
|
|
1019
1345
|
}}>
|
|
1020
|
-
{
|
|
1021
|
-
? '
|
|
1022
|
-
: '
|
|
1346
|
+
{isPersistent
|
|
1347
|
+
? t('settings.general.storageStatusEnabledDesc')
|
|
1348
|
+
: t('settings.general.storageStatusDisabledDesc')}
|
|
1023
1349
|
</Text>
|
|
1024
1350
|
</View>
|
|
1025
1351
|
</View>
|
|
1026
1352
|
</ScrollView>
|
|
1353
|
+
|
|
1354
|
+
{/* Bottom Sticky Action Bar for Save Changes */}
|
|
1355
|
+
{settingsActiveSubTab === 'module' && (<View style={{
|
|
1356
|
+
paddingHorizontal: 16,
|
|
1357
|
+
paddingTop: 12,
|
|
1358
|
+
paddingBottom: Platform.OS === 'ios' ? 26 : 14,
|
|
1359
|
+
backgroundColor: AppColors.primaryLight,
|
|
1360
|
+
borderTopWidth: 1,
|
|
1361
|
+
borderTopColor: AppColors.dividerColor,
|
|
1362
|
+
flexDirection: 'row',
|
|
1363
|
+
alignItems: 'center',
|
|
1364
|
+
gap: 12,
|
|
1365
|
+
shadowColor: AppColors.black,
|
|
1366
|
+
shadowOpacity: 0.08,
|
|
1367
|
+
shadowRadius: 8,
|
|
1368
|
+
shadowOffset: { width: 0, height: -3 },
|
|
1369
|
+
elevation: 8,
|
|
1370
|
+
}}>
|
|
1371
|
+
<View style={{ flex: 1 }}>
|
|
1372
|
+
<Text style={{
|
|
1373
|
+
fontFamily: AppFonts.interBold,
|
|
1374
|
+
fontSize: 13,
|
|
1375
|
+
lineHeight: 17,
|
|
1376
|
+
color: AppColors.primaryBlack,
|
|
1377
|
+
}}>
|
|
1378
|
+
{stagedActiveCount} of {allModules.length} Modules Active
|
|
1379
|
+
</Text>
|
|
1380
|
+
<Text style={{
|
|
1381
|
+
fontFamily: AppFonts.interRegular,
|
|
1382
|
+
fontSize: 11,
|
|
1383
|
+
lineHeight: 15,
|
|
1384
|
+
color: hasUnsavedChanges
|
|
1385
|
+
? AppColors.purple
|
|
1386
|
+
: AppColors.grayText,
|
|
1387
|
+
marginTop: 1,
|
|
1388
|
+
}}>
|
|
1389
|
+
{hasUnsavedChanges
|
|
1390
|
+
? t('settings.unsavedPending')
|
|
1391
|
+
: t('settings.allSynchronized')}
|
|
1392
|
+
</Text>
|
|
1393
|
+
</View>
|
|
1394
|
+
|
|
1395
|
+
<TouchableScale accessible={true} accessibilityRole="button" accessibilityLabel="Save Changes" onPress={handleSaveChanges} style={{
|
|
1396
|
+
flexDirection: 'row',
|
|
1397
|
+
alignItems: 'center',
|
|
1398
|
+
gap: 6,
|
|
1399
|
+
backgroundColor: hasUnsavedChanges
|
|
1400
|
+
? AppColors.purple
|
|
1401
|
+
: `${AppColors.purple}22`,
|
|
1402
|
+
paddingHorizontal: 18,
|
|
1403
|
+
paddingVertical: 10,
|
|
1404
|
+
borderRadius: 10,
|
|
1405
|
+
}}>
|
|
1406
|
+
<CheckIcon size={14} color={hasUnsavedChanges ? AppColors.white : AppColors.purple}/>
|
|
1407
|
+
<Text style={{
|
|
1408
|
+
fontFamily: AppFonts.interBold,
|
|
1409
|
+
fontSize: 13,
|
|
1410
|
+
lineHeight: 17,
|
|
1411
|
+
color: hasUnsavedChanges ? AppColors.white : AppColors.purple,
|
|
1412
|
+
}}>
|
|
1413
|
+
{t('settings.saveChanges')}
|
|
1414
|
+
</Text>
|
|
1415
|
+
</TouchableScale>
|
|
1416
|
+
</View>)}
|
|
1027
1417
|
</View>);
|
|
1028
1418
|
}
|
|
1029
1419
|
const goBackToMain = () => {
|
|
@@ -1057,6 +1447,7 @@ const SettingsPanel = () => {
|
|
|
1057
1447
|
<Text style={{
|
|
1058
1448
|
fontFamily: AppFonts.interBold,
|
|
1059
1449
|
fontSize: 14,
|
|
1450
|
+
lineHeight: 18,
|
|
1060
1451
|
color: AppColors.primaryBlack,
|
|
1061
1452
|
}}>
|
|
1062
1453
|
{opts.label}
|
|
@@ -1064,6 +1455,7 @@ const SettingsPanel = () => {
|
|
|
1064
1455
|
{opts.description ? (<Text style={{
|
|
1065
1456
|
fontFamily: AppFonts.interRegular,
|
|
1066
1457
|
fontSize: 11,
|
|
1458
|
+
lineHeight: 15,
|
|
1067
1459
|
color: AppColors.grayText,
|
|
1068
1460
|
marginTop: 1,
|
|
1069
1461
|
}}>
|
|
@@ -1095,6 +1487,7 @@ const SettingsPanel = () => {
|
|
|
1095
1487
|
<Text style={{
|
|
1096
1488
|
fontFamily: AppFonts.interBold,
|
|
1097
1489
|
fontSize: 11,
|
|
1490
|
+
lineHeight: 14,
|
|
1098
1491
|
color: isActive ? AppColors.white : AppColors.grayText,
|
|
1099
1492
|
}}>
|
|
1100
1493
|
{opts.picker.formatLabel
|
|
@@ -1110,22 +1503,21 @@ const SettingsPanel = () => {
|
|
|
1110
1503
|
let icon = null;
|
|
1111
1504
|
let rightInfo = '';
|
|
1112
1505
|
if (settingsPage === 'apis') {
|
|
1113
|
-
title = '
|
|
1506
|
+
title = t('settings.apis.title');
|
|
1114
1507
|
icon = <SignalIcon color={AppColors.white} size={16}/>;
|
|
1115
|
-
rightInfo =
|
|
1116
|
-
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16 }}>
|
|
1508
|
+
rightInfo = t('settings.apis.total', { count: logs.length });
|
|
1509
|
+
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 12 }}>
|
|
1117
1510
|
<View style={{
|
|
1118
1511
|
backgroundColor: AppColors.primaryLight,
|
|
1119
1512
|
padding: 16,
|
|
1120
|
-
borderRadius:
|
|
1513
|
+
borderRadius: 14,
|
|
1121
1514
|
borderWidth: 1,
|
|
1122
1515
|
borderColor: AppColors.grayBorderSecondary,
|
|
1123
|
-
gap: 4,
|
|
1124
1516
|
}}>
|
|
1125
1517
|
{renderSettingRow({
|
|
1126
1518
|
icon: <SignalIcon color={AppColors.purple} size={16}/>,
|
|
1127
|
-
label: '
|
|
1128
|
-
description: '
|
|
1519
|
+
label: t('settings.apis.maxRequestLogs'),
|
|
1520
|
+
description: t('settings.apis.maxRequestLogsDescription'),
|
|
1129
1521
|
picker: {
|
|
1130
1522
|
options: [50, 100, 200, 500],
|
|
1131
1523
|
selectedValue: maxNetworkLogs,
|
|
@@ -1137,26 +1529,25 @@ const SettingsPanel = () => {
|
|
|
1137
1529
|
|
|
1138
1530
|
<View style={{
|
|
1139
1531
|
backgroundColor: AppColors.primaryLight,
|
|
1140
|
-
borderRadius:
|
|
1532
|
+
borderRadius: 14,
|
|
1141
1533
|
borderWidth: 1,
|
|
1142
1534
|
borderColor: AppColors.grayBorderSecondary,
|
|
1143
1535
|
padding: 16,
|
|
1144
|
-
marginTop: 12,
|
|
1145
1536
|
}}>
|
|
1146
1537
|
{renderSettingRow({
|
|
1147
1538
|
icon: <TrashIcon color={AppColors.errorColor} size={16}/>,
|
|
1148
|
-
label: '
|
|
1149
|
-
description:
|
|
1539
|
+
label: t('settings.apis.clearNetworkLogs'),
|
|
1540
|
+
description: t('settings.apis.clearNetworkLogsDescription', { count: logs.length }),
|
|
1150
1541
|
isLast: true,
|
|
1151
1542
|
onPress: () => {
|
|
1152
1543
|
clearNetworkLogs();
|
|
1153
1544
|
setSelected(null);
|
|
1154
|
-
Alert.alert('
|
|
1545
|
+
Alert.alert(t('common.success'), t('settings.apis.networkLogsCleared'));
|
|
1155
1546
|
},
|
|
1156
1547
|
right: (<View style={{
|
|
1157
|
-
paddingHorizontal:
|
|
1158
|
-
paddingVertical:
|
|
1159
|
-
borderRadius:
|
|
1548
|
+
paddingHorizontal: 12,
|
|
1549
|
+
paddingVertical: 6,
|
|
1550
|
+
borderRadius: 8,
|
|
1160
1551
|
backgroundColor: `${AppColors.errorColor}14`,
|
|
1161
1552
|
borderWidth: 1,
|
|
1162
1553
|
borderColor: `${AppColors.errorColor}33`,
|
|
@@ -1164,9 +1555,10 @@ const SettingsPanel = () => {
|
|
|
1164
1555
|
<Text style={{
|
|
1165
1556
|
fontFamily: AppFonts.interBold,
|
|
1166
1557
|
fontSize: 11,
|
|
1558
|
+
lineHeight: 14,
|
|
1167
1559
|
color: AppColors.errorColor,
|
|
1168
1560
|
}}>
|
|
1169
|
-
|
|
1561
|
+
{t('common.clear')}
|
|
1170
1562
|
</Text>
|
|
1171
1563
|
</View>),
|
|
1172
1564
|
})}
|
|
@@ -1174,22 +1566,22 @@ const SettingsPanel = () => {
|
|
|
1174
1566
|
</ScrollView>);
|
|
1175
1567
|
}
|
|
1176
1568
|
else if (settingsPage === 'logs') {
|
|
1177
|
-
title = '
|
|
1569
|
+
title = t('settings.logs.title');
|
|
1178
1570
|
icon = <TerminalIcon color={AppColors.white} size={16}/>;
|
|
1179
|
-
rightInfo =
|
|
1180
|
-
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16 }}>
|
|
1571
|
+
rightInfo = t('settings.logs.total', { count: consoleLogs.length });
|
|
1572
|
+
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 12 }}>
|
|
1181
1573
|
<View style={{
|
|
1182
1574
|
backgroundColor: AppColors.primaryLight,
|
|
1183
1575
|
padding: 16,
|
|
1184
|
-
borderRadius:
|
|
1576
|
+
borderRadius: 14,
|
|
1185
1577
|
borderWidth: 1,
|
|
1186
1578
|
borderColor: AppColors.grayBorderSecondary,
|
|
1187
1579
|
gap: 4,
|
|
1188
1580
|
}}>
|
|
1189
1581
|
{renderSettingRow({
|
|
1190
1582
|
icon: <TerminalIcon color={AppColors.purple} size={16}/>,
|
|
1191
|
-
label: '
|
|
1192
|
-
description: '
|
|
1583
|
+
label: t('settings.logs.maxConsoleLogs'),
|
|
1584
|
+
description: t('settings.logs.maxConsoleLogsDescription'),
|
|
1193
1585
|
picker: {
|
|
1194
1586
|
options: [100, 200, 500, 1000],
|
|
1195
1587
|
selectedValue: maxConsoleLogs,
|
|
@@ -1200,10 +1592,11 @@ const SettingsPanel = () => {
|
|
|
1200
1592
|
<Text style={{
|
|
1201
1593
|
fontFamily: AppFonts.interBold,
|
|
1202
1594
|
fontSize: 13,
|
|
1595
|
+
lineHeight: 17,
|
|
1203
1596
|
color: AppColors.primaryBlack,
|
|
1204
|
-
paddingTop:
|
|
1597
|
+
paddingTop: 6,
|
|
1205
1598
|
}}>
|
|
1206
|
-
|
|
1599
|
+
{t('settings.logs.logLevels')}
|
|
1207
1600
|
</Text>
|
|
1208
1601
|
{['info', 'warn', 'error'].map(level => {
|
|
1209
1602
|
const isLvlActive = showConsoleLevels?.[level];
|
|
@@ -1212,19 +1605,25 @@ const SettingsPanel = () => {
|
|
|
1212
1605
|
: level === 'warn'
|
|
1213
1606
|
? AppColors.warningIconGold
|
|
1214
1607
|
: AppColors.skyBlue;
|
|
1608
|
+
const label = level === 'info'
|
|
1609
|
+
? t('settings.logs.showInfo')
|
|
1610
|
+
: level === 'warn'
|
|
1611
|
+
? t('settings.logs.showWarn')
|
|
1612
|
+
: t('settings.logs.showError');
|
|
1613
|
+
const desc = level === 'info'
|
|
1614
|
+
? t('settings.logs.showInfoDesc')
|
|
1615
|
+
: level === 'warn'
|
|
1616
|
+
? t('settings.logs.showWarnDesc')
|
|
1617
|
+
: t('settings.logs.showErrorDesc');
|
|
1215
1618
|
return renderSettingRow({
|
|
1216
1619
|
icon: (<View style={{
|
|
1217
|
-
width:
|
|
1218
|
-
height:
|
|
1219
|
-
borderRadius:
|
|
1620
|
+
width: 12,
|
|
1621
|
+
height: 12,
|
|
1622
|
+
borderRadius: 6,
|
|
1220
1623
|
backgroundColor: levelColor,
|
|
1221
1624
|
}}/>),
|
|
1222
|
-
label
|
|
1223
|
-
description:
|
|
1224
|
-
? 'Informational messages'
|
|
1225
|
-
: level === 'warn'
|
|
1226
|
-
? 'Warning messages'
|
|
1227
|
-
: 'Error messages',
|
|
1625
|
+
label,
|
|
1626
|
+
description: desc,
|
|
1228
1627
|
isLast: level === 'error',
|
|
1229
1628
|
onPress: () => setShowConsoleLevels(prev => ({
|
|
1230
1629
|
...prev,
|
|
@@ -1252,25 +1651,24 @@ const SettingsPanel = () => {
|
|
|
1252
1651
|
|
|
1253
1652
|
<View style={{
|
|
1254
1653
|
backgroundColor: AppColors.primaryLight,
|
|
1255
|
-
borderRadius:
|
|
1654
|
+
borderRadius: 14,
|
|
1256
1655
|
borderWidth: 1,
|
|
1257
1656
|
borderColor: AppColors.grayBorderSecondary,
|
|
1258
1657
|
padding: 16,
|
|
1259
|
-
marginTop: 12,
|
|
1260
1658
|
}}>
|
|
1261
1659
|
{renderSettingRow({
|
|
1262
1660
|
icon: <TrashIcon color={AppColors.errorColor} size={16}/>,
|
|
1263
|
-
label: '
|
|
1264
|
-
description:
|
|
1661
|
+
label: t('settings.logs.clearConsoleLogs'),
|
|
1662
|
+
description: t('settings.logs.clearConsoleLogsDescription', { count: consoleLogs.length }),
|
|
1265
1663
|
isLast: true,
|
|
1266
1664
|
onPress: () => {
|
|
1267
1665
|
clearConsoleLogs();
|
|
1268
|
-
Alert.alert('
|
|
1666
|
+
Alert.alert(t('common.success'), t('settings.logs.consoleLogsCleared'));
|
|
1269
1667
|
},
|
|
1270
1668
|
right: (<View style={{
|
|
1271
|
-
paddingHorizontal:
|
|
1272
|
-
paddingVertical:
|
|
1273
|
-
borderRadius:
|
|
1669
|
+
paddingHorizontal: 12,
|
|
1670
|
+
paddingVertical: 6,
|
|
1671
|
+
borderRadius: 8,
|
|
1274
1672
|
backgroundColor: `${AppColors.errorColor}14`,
|
|
1275
1673
|
borderWidth: 1,
|
|
1276
1674
|
borderColor: `${AppColors.errorColor}33`,
|
|
@@ -1278,9 +1676,10 @@ const SettingsPanel = () => {
|
|
|
1278
1676
|
<Text style={{
|
|
1279
1677
|
fontFamily: AppFonts.interBold,
|
|
1280
1678
|
fontSize: 11,
|
|
1679
|
+
lineHeight: 14,
|
|
1281
1680
|
color: AppColors.errorColor,
|
|
1282
1681
|
}}>
|
|
1283
|
-
|
|
1682
|
+
{t('common.clear')}
|
|
1284
1683
|
</Text>
|
|
1285
1684
|
</View>),
|
|
1286
1685
|
})}
|
|
@@ -1288,47 +1687,45 @@ const SettingsPanel = () => {
|
|
|
1288
1687
|
</ScrollView>);
|
|
1289
1688
|
}
|
|
1290
1689
|
else if (settingsPage === 'analytics') {
|
|
1291
|
-
title = '
|
|
1690
|
+
title = t('settings.analytics.title');
|
|
1292
1691
|
icon = <AnalyticsIcon color={AppColors.white} size={16}/>;
|
|
1293
|
-
rightInfo =
|
|
1294
|
-
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16 }}>
|
|
1692
|
+
rightInfo = t('settings.analytics.total', { count: analyticsEvents.length });
|
|
1693
|
+
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 12 }}>
|
|
1295
1694
|
<View style={{
|
|
1296
1695
|
backgroundColor: AppColors.primaryLight,
|
|
1297
1696
|
padding: 16,
|
|
1298
|
-
borderRadius:
|
|
1697
|
+
borderRadius: 14,
|
|
1299
1698
|
borderWidth: 1,
|
|
1300
1699
|
borderColor: AppColors.grayBorderSecondary,
|
|
1301
|
-
gap: 4,
|
|
1302
1700
|
}}>
|
|
1303
1701
|
{renderSettingRow({
|
|
1304
1702
|
icon: <AnalyticsIcon color={AppColors.purple} size={16}/>,
|
|
1305
|
-
label: '
|
|
1306
|
-
description:
|
|
1703
|
+
label: t('settings.analytics.maxAnalyticsEvents'),
|
|
1704
|
+
description: t('settings.analytics.maxAnalyticsEventsDescription', { count: analyticsEvents.length }),
|
|
1307
1705
|
isLast: true,
|
|
1308
1706
|
})}
|
|
1309
1707
|
</View>
|
|
1310
1708
|
<View style={{
|
|
1311
1709
|
backgroundColor: AppColors.primaryLight,
|
|
1312
|
-
borderRadius:
|
|
1710
|
+
borderRadius: 14,
|
|
1313
1711
|
borderWidth: 1,
|
|
1314
1712
|
borderColor: AppColors.grayBorderSecondary,
|
|
1315
1713
|
padding: 16,
|
|
1316
|
-
marginTop: 12,
|
|
1317
1714
|
}}>
|
|
1318
1715
|
{renderSettingRow({
|
|
1319
1716
|
icon: <TrashIcon color={AppColors.errorColor} size={16}/>,
|
|
1320
|
-
label: '
|
|
1321
|
-
description: '
|
|
1717
|
+
label: t('settings.analytics.clearAnalyticsEvents'),
|
|
1718
|
+
description: t('settings.analytics.clearAnalyticsEventsDescription'),
|
|
1322
1719
|
isLast: true,
|
|
1323
1720
|
onPress: () => {
|
|
1324
1721
|
clearAnalyticsEvents();
|
|
1325
1722
|
setSelectedEvent(null);
|
|
1326
|
-
Alert.alert('
|
|
1723
|
+
Alert.alert(t('common.success'), t('settings.analytics.analyticsEventsCleared'));
|
|
1327
1724
|
},
|
|
1328
1725
|
right: (<View style={{
|
|
1329
|
-
paddingHorizontal:
|
|
1330
|
-
paddingVertical:
|
|
1331
|
-
borderRadius:
|
|
1726
|
+
paddingHorizontal: 12,
|
|
1727
|
+
paddingVertical: 6,
|
|
1728
|
+
borderRadius: 8,
|
|
1332
1729
|
backgroundColor: `${AppColors.errorColor}14`,
|
|
1333
1730
|
borderWidth: 1,
|
|
1334
1731
|
borderColor: `${AppColors.errorColor}33`,
|
|
@@ -1336,9 +1733,10 @@ const SettingsPanel = () => {
|
|
|
1336
1733
|
<Text style={{
|
|
1337
1734
|
fontFamily: AppFonts.interBold,
|
|
1338
1735
|
fontSize: 11,
|
|
1736
|
+
lineHeight: 14,
|
|
1339
1737
|
color: AppColors.errorColor,
|
|
1340
1738
|
}}>
|
|
1341
|
-
|
|
1739
|
+
{t('common.clear')}
|
|
1342
1740
|
</Text>
|
|
1343
1741
|
</View>),
|
|
1344
1742
|
})}
|
|
@@ -1346,22 +1744,22 @@ const SettingsPanel = () => {
|
|
|
1346
1744
|
</ScrollView>);
|
|
1347
1745
|
}
|
|
1348
1746
|
else if (settingsPage === 'redux') {
|
|
1349
|
-
title = '
|
|
1350
|
-
icon = <
|
|
1351
|
-
rightInfo =
|
|
1352
|
-
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16 }}>
|
|
1747
|
+
title = t('settings.redux.title');
|
|
1748
|
+
icon = <ReduxIcon color={AppColors.white} size={16}/>;
|
|
1749
|
+
rightInfo = t('settings.redux.reducers', { count: Object.keys(reduxState || {}).length });
|
|
1750
|
+
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 12 }}>
|
|
1353
1751
|
<View style={{
|
|
1354
1752
|
backgroundColor: AppColors.primaryLight,
|
|
1355
1753
|
padding: 16,
|
|
1356
|
-
borderRadius:
|
|
1754
|
+
borderRadius: 14,
|
|
1357
1755
|
borderWidth: 1,
|
|
1358
1756
|
borderColor: AppColors.grayBorderSecondary,
|
|
1359
1757
|
gap: 4,
|
|
1360
1758
|
}}>
|
|
1361
1759
|
{renderSettingRow({
|
|
1362
|
-
icon: <
|
|
1363
|
-
label: '
|
|
1364
|
-
description: '
|
|
1760
|
+
icon: <ReduxIcon color={AppColors.purple} size={16}/>,
|
|
1761
|
+
label: t('settings.redux.autoRefresh'),
|
|
1762
|
+
description: t('settings.redux.autoRefreshDescription'),
|
|
1365
1763
|
onPress: () => setReduxAutoRefreshState(prev => !prev),
|
|
1366
1764
|
right: (<View style={{
|
|
1367
1765
|
width: 22,
|
|
@@ -1383,8 +1781,8 @@ const SettingsPanel = () => {
|
|
|
1383
1781
|
<View style={{ height: 1, backgroundColor: AppColors.dividerColor }}/>
|
|
1384
1782
|
{renderSettingRow({
|
|
1385
1783
|
icon: <LayersIcon color={AppColors.purple} size={16}/>,
|
|
1386
|
-
label: '
|
|
1387
|
-
description: '
|
|
1784
|
+
label: t('settings.redux.defaultJsonExpandDepth'),
|
|
1785
|
+
description: t('settings.redux.defaultJsonExpandDepthDescription'),
|
|
1388
1786
|
picker: {
|
|
1389
1787
|
options: [1, 2, 3, 5],
|
|
1390
1788
|
selectedValue: reduxExpandDepth,
|
|
@@ -1396,27 +1794,26 @@ const SettingsPanel = () => {
|
|
|
1396
1794
|
|
|
1397
1795
|
<View style={{
|
|
1398
1796
|
backgroundColor: AppColors.primaryLight,
|
|
1399
|
-
borderRadius:
|
|
1797
|
+
borderRadius: 14,
|
|
1400
1798
|
borderWidth: 1,
|
|
1401
1799
|
borderColor: AppColors.grayBorderSecondary,
|
|
1402
1800
|
padding: 16,
|
|
1403
|
-
marginTop: 12,
|
|
1404
1801
|
}}>
|
|
1405
1802
|
{renderSettingRow({
|
|
1406
1803
|
icon: <TrashIcon color={AppColors.errorColor} size={16}/>,
|
|
1407
|
-
label: '
|
|
1804
|
+
label: t('settings.redux.clearReduxState'),
|
|
1408
1805
|
description: reduxState
|
|
1409
|
-
? '
|
|
1410
|
-
: '
|
|
1806
|
+
? t('settings.redux.clearReduxStateDescription')
|
|
1807
|
+
: t('settings.redux.clearReduxStateEmpty'),
|
|
1411
1808
|
isLast: true,
|
|
1412
1809
|
onPress: () => {
|
|
1413
1810
|
setReduxState(null);
|
|
1414
|
-
Alert.alert('
|
|
1811
|
+
Alert.alert(t('common.success'), t('settings.redux.reduxStateCleared'));
|
|
1415
1812
|
},
|
|
1416
1813
|
right: (<View style={{
|
|
1417
|
-
paddingHorizontal:
|
|
1418
|
-
paddingVertical:
|
|
1419
|
-
borderRadius:
|
|
1814
|
+
paddingHorizontal: 12,
|
|
1815
|
+
paddingVertical: 6,
|
|
1816
|
+
borderRadius: 8,
|
|
1420
1817
|
backgroundColor: `${AppColors.errorColor}14`,
|
|
1421
1818
|
borderWidth: 1,
|
|
1422
1819
|
borderColor: `${AppColors.errorColor}33`,
|
|
@@ -1424,9 +1821,10 @@ const SettingsPanel = () => {
|
|
|
1424
1821
|
<Text style={{
|
|
1425
1822
|
fontFamily: AppFonts.interBold,
|
|
1426
1823
|
fontSize: 11,
|
|
1824
|
+
lineHeight: 14,
|
|
1427
1825
|
color: AppColors.errorColor,
|
|
1428
1826
|
}}>
|
|
1429
|
-
|
|
1827
|
+
{t('common.clear')}
|
|
1430
1828
|
</Text>
|
|
1431
1829
|
</View>),
|
|
1432
1830
|
})}
|
|
@@ -1434,22 +1832,22 @@ const SettingsPanel = () => {
|
|
|
1434
1832
|
</ScrollView>);
|
|
1435
1833
|
}
|
|
1436
1834
|
else if (settingsPage === 'crash') {
|
|
1437
|
-
title = '
|
|
1835
|
+
title = t('settings.crash.title');
|
|
1438
1836
|
icon = <CrashIcon color={AppColors.white} size={16}/>;
|
|
1439
1837
|
rightInfo = `Total: ${crashRecords?.length || 0}`;
|
|
1440
|
-
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16 }}>
|
|
1838
|
+
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 12 }}>
|
|
1441
1839
|
<View style={{
|
|
1442
1840
|
backgroundColor: AppColors.primaryLight,
|
|
1443
1841
|
padding: 16,
|
|
1444
|
-
borderRadius:
|
|
1842
|
+
borderRadius: 14,
|
|
1445
1843
|
borderWidth: 1,
|
|
1446
1844
|
borderColor: AppColors.grayBorderSecondary,
|
|
1447
1845
|
gap: 4,
|
|
1448
1846
|
}}>
|
|
1449
1847
|
{renderSettingRow({
|
|
1450
1848
|
icon: <LayersIcon color={AppColors.purple} size={16}/>,
|
|
1451
|
-
label: '
|
|
1452
|
-
description: '
|
|
1849
|
+
label: t('settings.crash.maxCrashLogs'),
|
|
1850
|
+
description: t('settings.crash.maxCrashLogsDesc'),
|
|
1453
1851
|
picker: {
|
|
1454
1852
|
options: [25, 50, 100, 200],
|
|
1455
1853
|
selectedValue: maxCrashLogs || 100,
|
|
@@ -1459,8 +1857,8 @@ const SettingsPanel = () => {
|
|
|
1459
1857
|
<View style={{ height: 1, backgroundColor: AppColors.dividerColor }}/>
|
|
1460
1858
|
{renderSettingRow({
|
|
1461
1859
|
icon: <ShieldAlertIcon color={AppColors.greenColor} size={16}/>,
|
|
1462
|
-
label: '
|
|
1463
|
-
description: '
|
|
1860
|
+
label: t('settings.crash.globalGuard'),
|
|
1861
|
+
description: t('settings.crash.globalGuardDesc'),
|
|
1464
1862
|
isLast: true,
|
|
1465
1863
|
right: (<View style={{
|
|
1466
1864
|
paddingHorizontal: 8,
|
|
@@ -1471,9 +1869,10 @@ const SettingsPanel = () => {
|
|
|
1471
1869
|
<Text style={{
|
|
1472
1870
|
fontFamily: AppFonts.interBold,
|
|
1473
1871
|
fontSize: 10,
|
|
1872
|
+
lineHeight: 13,
|
|
1474
1873
|
color: AppColors.greenColor,
|
|
1475
1874
|
}}>
|
|
1476
|
-
|
|
1875
|
+
{t('settings.protectedBadge')}
|
|
1477
1876
|
</Text>
|
|
1478
1877
|
</View>),
|
|
1479
1878
|
})}
|
|
@@ -1481,25 +1880,190 @@ const SettingsPanel = () => {
|
|
|
1481
1880
|
|
|
1482
1881
|
<View style={{
|
|
1483
1882
|
backgroundColor: AppColors.primaryLight,
|
|
1484
|
-
borderRadius:
|
|
1883
|
+
borderRadius: 14,
|
|
1485
1884
|
borderWidth: 1,
|
|
1486
1885
|
borderColor: AppColors.grayBorderSecondary,
|
|
1487
1886
|
padding: 16,
|
|
1488
|
-
marginTop: 12,
|
|
1489
1887
|
}}>
|
|
1490
1888
|
{renderSettingRow({
|
|
1491
1889
|
icon: <TrashIcon color={AppColors.errorColor} size={16}/>,
|
|
1492
|
-
label: '
|
|
1493
|
-
description:
|
|
1890
|
+
label: t('settings.crash.clearHistory'),
|
|
1891
|
+
description: t('settings.crash.clearHistoryDesc', { count: crashRecords?.length || 0 }),
|
|
1494
1892
|
isLast: true,
|
|
1495
1893
|
onPress: () => {
|
|
1496
1894
|
clearCrashRecords();
|
|
1497
|
-
Alert.alert('
|
|
1895
|
+
Alert.alert(t('common.success'), t('settings.crash.historyCleared'));
|
|
1896
|
+
},
|
|
1897
|
+
right: (<View style={{
|
|
1898
|
+
paddingHorizontal: 12,
|
|
1899
|
+
paddingVertical: 6,
|
|
1900
|
+
borderRadius: 8,
|
|
1901
|
+
backgroundColor: `${AppColors.errorColor}14`,
|
|
1902
|
+
borderWidth: 1,
|
|
1903
|
+
borderColor: `${AppColors.errorColor}33`,
|
|
1904
|
+
}}>
|
|
1905
|
+
<Text style={{
|
|
1906
|
+
fontFamily: AppFonts.interBold,
|
|
1907
|
+
fontSize: 11,
|
|
1908
|
+
lineHeight: 14,
|
|
1909
|
+
color: AppColors.errorColor,
|
|
1910
|
+
}}>
|
|
1911
|
+
{t('common.clear')}
|
|
1912
|
+
</Text>
|
|
1913
|
+
</View>),
|
|
1914
|
+
})}
|
|
1915
|
+
</View>
|
|
1916
|
+
</ScrollView>);
|
|
1917
|
+
}
|
|
1918
|
+
else if (settingsPage === 'bundle') {
|
|
1919
|
+
title = t('settings.bundle.title');
|
|
1920
|
+
icon = <PackageIcon color={AppColors.white} size={16}/>;
|
|
1921
|
+
rightInfo = 'Metro';
|
|
1922
|
+
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 12 }}>
|
|
1923
|
+
<View style={{
|
|
1924
|
+
backgroundColor: AppColors.primaryLight,
|
|
1925
|
+
padding: 16,
|
|
1926
|
+
borderRadius: 14,
|
|
1927
|
+
borderWidth: 1,
|
|
1928
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
1929
|
+
gap: 8,
|
|
1930
|
+
}}>
|
|
1931
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 10 }}>
|
|
1932
|
+
<View style={{
|
|
1933
|
+
width: 36,
|
|
1934
|
+
height: 36,
|
|
1935
|
+
borderRadius: 10,
|
|
1936
|
+
backgroundColor: AppColors.purpleShade50,
|
|
1937
|
+
alignItems: 'center',
|
|
1938
|
+
justifyContent: 'center',
|
|
1939
|
+
}}>
|
|
1940
|
+
<PackageIcon color={AppColors.purple} size={16}/>
|
|
1941
|
+
</View>
|
|
1942
|
+
<View style={{ flex: 1 }}>
|
|
1943
|
+
<Text style={{
|
|
1944
|
+
fontFamily: AppFonts.interBold,
|
|
1945
|
+
fontSize: 14,
|
|
1946
|
+
lineHeight: 18,
|
|
1947
|
+
color: AppColors.primaryBlack,
|
|
1948
|
+
}}>
|
|
1949
|
+
{t('settings.bundle.sourceBundler')}
|
|
1950
|
+
</Text>
|
|
1951
|
+
<Text style={{
|
|
1952
|
+
fontFamily: AppFonts.interRegular,
|
|
1953
|
+
fontSize: 11,
|
|
1954
|
+
lineHeight: 15,
|
|
1955
|
+
color: AppColors.grayText,
|
|
1956
|
+
marginTop: 1,
|
|
1957
|
+
}}>
|
|
1958
|
+
{t('settings.bundle.sourceBundlerDesc')}
|
|
1959
|
+
</Text>
|
|
1960
|
+
</View>
|
|
1961
|
+
</View>
|
|
1962
|
+
</View>
|
|
1963
|
+
|
|
1964
|
+
<View style={{
|
|
1965
|
+
backgroundColor: AppColors.primaryLight,
|
|
1966
|
+
borderRadius: 14,
|
|
1967
|
+
borderWidth: 1,
|
|
1968
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
1969
|
+
padding: 16,
|
|
1970
|
+
}}>
|
|
1971
|
+
{renderSettingRow({
|
|
1972
|
+
icon: <TrashIcon color={AppColors.errorColor} size={16}/>,
|
|
1973
|
+
label: t('settings.bundle.clearCache'),
|
|
1974
|
+
description: t('settings.bundle.clearCacheDesc'),
|
|
1975
|
+
isLast: true,
|
|
1976
|
+
onPress: () => {
|
|
1977
|
+
clearCachedBundleAnalysis();
|
|
1978
|
+
Alert.alert(t('common.success'), t('settings.bundle.cacheCleared'));
|
|
1979
|
+
},
|
|
1980
|
+
right: (<View style={{
|
|
1981
|
+
paddingHorizontal: 12,
|
|
1982
|
+
paddingVertical: 6,
|
|
1983
|
+
borderRadius: 8,
|
|
1984
|
+
backgroundColor: `${AppColors.errorColor}14`,
|
|
1985
|
+
borderWidth: 1,
|
|
1986
|
+
borderColor: `${AppColors.errorColor}33`,
|
|
1987
|
+
}}>
|
|
1988
|
+
<Text style={{
|
|
1989
|
+
fontFamily: AppFonts.interBold,
|
|
1990
|
+
fontSize: 11,
|
|
1991
|
+
lineHeight: 14,
|
|
1992
|
+
color: AppColors.errorColor,
|
|
1993
|
+
}}>
|
|
1994
|
+
{t('common.clear')}
|
|
1995
|
+
</Text>
|
|
1996
|
+
</View>),
|
|
1997
|
+
})}
|
|
1998
|
+
</View>
|
|
1999
|
+
</ScrollView>);
|
|
2000
|
+
}
|
|
2001
|
+
else if (settingsPage === 'performance') {
|
|
2002
|
+
title = t('settings.performance.title');
|
|
2003
|
+
icon = <PerformanceIcon color={AppColors.white} size={16}/>;
|
|
2004
|
+
rightInfo = '60 FPS Target';
|
|
2005
|
+
content = (<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 12 }}>
|
|
2006
|
+
<View style={{
|
|
2007
|
+
backgroundColor: AppColors.primaryLight,
|
|
2008
|
+
padding: 16,
|
|
2009
|
+
borderRadius: 14,
|
|
2010
|
+
borderWidth: 1,
|
|
2011
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
2012
|
+
gap: 8,
|
|
2013
|
+
}}>
|
|
2014
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 10 }}>
|
|
2015
|
+
<View style={{
|
|
2016
|
+
width: 36,
|
|
2017
|
+
height: 36,
|
|
2018
|
+
borderRadius: 10,
|
|
2019
|
+
backgroundColor: AppColors.purpleShade50,
|
|
2020
|
+
alignItems: 'center',
|
|
2021
|
+
justifyContent: 'center',
|
|
2022
|
+
}}>
|
|
2023
|
+
<PerformanceIcon color={AppColors.purple} size={16}/>
|
|
2024
|
+
</View>
|
|
2025
|
+
<View style={{ flex: 1 }}>
|
|
2026
|
+
<Text style={{
|
|
2027
|
+
fontFamily: AppFonts.interBold,
|
|
2028
|
+
fontSize: 14,
|
|
2029
|
+
lineHeight: 18,
|
|
2030
|
+
color: AppColors.primaryBlack,
|
|
2031
|
+
}}>
|
|
2032
|
+
{t('settings.performance.frameMeasurement')}
|
|
2033
|
+
</Text>
|
|
2034
|
+
<Text style={{
|
|
2035
|
+
fontFamily: AppFonts.interRegular,
|
|
2036
|
+
fontSize: 11,
|
|
2037
|
+
lineHeight: 15,
|
|
2038
|
+
color: AppColors.grayText,
|
|
2039
|
+
marginTop: 1,
|
|
2040
|
+
}}>
|
|
2041
|
+
{t('settings.performance.frameMeasurementDesc')}
|
|
2042
|
+
</Text>
|
|
2043
|
+
</View>
|
|
2044
|
+
</View>
|
|
2045
|
+
</View>
|
|
2046
|
+
|
|
2047
|
+
<View style={{
|
|
2048
|
+
backgroundColor: AppColors.primaryLight,
|
|
2049
|
+
borderRadius: 14,
|
|
2050
|
+
borderWidth: 1,
|
|
2051
|
+
borderColor: AppColors.grayBorderSecondary,
|
|
2052
|
+
padding: 16,
|
|
2053
|
+
}}>
|
|
2054
|
+
{renderSettingRow({
|
|
2055
|
+
icon: <TrashIcon color={AppColors.errorColor} size={16}/>,
|
|
2056
|
+
label: t('settings.performance.clearEvents'),
|
|
2057
|
+
description: t('settings.performance.clearEventsDesc'),
|
|
2058
|
+
isLast: true,
|
|
2059
|
+
onPress: () => {
|
|
2060
|
+
clearPerformanceEvents();
|
|
2061
|
+
Alert.alert(t('common.success'), t('settings.performance.eventsCleared'));
|
|
1498
2062
|
},
|
|
1499
2063
|
right: (<View style={{
|
|
1500
|
-
paddingHorizontal:
|
|
1501
|
-
paddingVertical:
|
|
1502
|
-
borderRadius:
|
|
2064
|
+
paddingHorizontal: 12,
|
|
2065
|
+
paddingVertical: 6,
|
|
2066
|
+
borderRadius: 8,
|
|
1503
2067
|
backgroundColor: `${AppColors.errorColor}14`,
|
|
1504
2068
|
borderWidth: 1,
|
|
1505
2069
|
borderColor: `${AppColors.errorColor}33`,
|
|
@@ -1507,29 +2071,33 @@ const SettingsPanel = () => {
|
|
|
1507
2071
|
<Text style={{
|
|
1508
2072
|
fontFamily: AppFonts.interBold,
|
|
1509
2073
|
fontSize: 11,
|
|
2074
|
+
lineHeight: 14,
|
|
1510
2075
|
color: AppColors.errorColor,
|
|
1511
2076
|
}}>
|
|
1512
|
-
|
|
2077
|
+
{t('common.clear')}
|
|
1513
2078
|
</Text>
|
|
1514
2079
|
</View>),
|
|
1515
2080
|
})}
|
|
1516
2081
|
</View>
|
|
1517
2082
|
</ScrollView>);
|
|
1518
2083
|
}
|
|
1519
|
-
return (<View style={{
|
|
2084
|
+
return (<View style={{
|
|
2085
|
+
flex: 1,
|
|
2086
|
+
backgroundColor: AppColors.grayBackground,
|
|
2087
|
+
}}>
|
|
1520
2088
|
<LinearGradient colors={[AppColors.purple, AppColors.brandPurple]} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles.headerGradient}>
|
|
1521
2089
|
<View style={{ paddingTop: headerTopPadding, width: '100%' }}>
|
|
1522
2090
|
<View style={[styles.header, { paddingHorizontal: 16, gap: 12 }]}>
|
|
1523
|
-
|
|
2091
|
+
<TouchableScale accessible={true} accessibilityRole="button" accessibilityLabel={t('settings.back')} onPress={goBackToMain} hitSlop={12} style={{
|
|
1524
2092
|
padding: 8,
|
|
1525
2093
|
borderRadius: 10,
|
|
1526
2094
|
backgroundColor: `${AppColors.white}26`,
|
|
1527
2095
|
borderWidth: 1,
|
|
1528
2096
|
borderColor: `${AppColors.white}14`,
|
|
1529
2097
|
}}>
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
2098
|
+
<WhiteBackNavigation color={AppColors.white} size={16}/>
|
|
2099
|
+
</TouchableScale>
|
|
2100
|
+
{icon && (<View style={{
|
|
1533
2101
|
width: 30,
|
|
1534
2102
|
height: 30,
|
|
1535
2103
|
borderRadius: 8,
|
|
@@ -1537,18 +2105,19 @@ const SettingsPanel = () => {
|
|
|
1537
2105
|
alignItems: 'center',
|
|
1538
2106
|
justifyContent: 'center',
|
|
1539
2107
|
}}>
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
2108
|
+
{icon}
|
|
2109
|
+
</View>)}
|
|
2110
|
+
<View style={{ flex: 1 }}>
|
|
2111
|
+
<Text style={{
|
|
1544
2112
|
fontFamily: AppFonts.interBold,
|
|
1545
2113
|
fontSize: 17,
|
|
2114
|
+
lineHeight: 22,
|
|
1546
2115
|
color: AppColors.white,
|
|
1547
2116
|
}}>
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
2117
|
+
{title}
|
|
2118
|
+
</Text>
|
|
2119
|
+
</View>
|
|
2120
|
+
{rightInfo ? (<View style={{
|
|
1552
2121
|
backgroundColor: `${AppColors.white}26`,
|
|
1553
2122
|
paddingHorizontal: 8,
|
|
1554
2123
|
paddingVertical: 4,
|
|
@@ -1556,17 +2125,18 @@ const SettingsPanel = () => {
|
|
|
1556
2125
|
borderWidth: 1,
|
|
1557
2126
|
borderColor: `${AppColors.white}1A`,
|
|
1558
2127
|
}}>
|
|
1559
|
-
|
|
2128
|
+
<Text style={{
|
|
1560
2129
|
fontFamily: AppFonts.interBold,
|
|
1561
2130
|
fontSize: 11,
|
|
2131
|
+
lineHeight: 14,
|
|
1562
2132
|
color: AppColors.white,
|
|
1563
2133
|
}}>
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
2134
|
+
{rightInfo}
|
|
2135
|
+
</Text>
|
|
2136
|
+
</View>) : null}
|
|
2137
|
+
</View>
|
|
1567
2138
|
</View>
|
|
1568
|
-
</
|
|
1569
|
-
</LinearGradient>
|
|
2139
|
+
</LinearGradient>
|
|
1570
2140
|
{content}
|
|
1571
2141
|
</View>);
|
|
1572
2142
|
};
|