react-native-inapp-inspector 1.1.12 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/components/AnalyticsDetail.js +64 -21
- package/dist/commonjs/components/HighlightText.js +1 -1
- package/dist/commonjs/components/JsonViewer.d.ts +3 -1
- package/dist/commonjs/components/JsonViewer.js +327 -9
- package/dist/commonjs/components/MetaAccordion.d.ts +10 -1
- package/dist/commonjs/components/MetaAccordion.js +121 -24
- package/dist/commonjs/components/NetworkIcons.d.ts +1 -0
- package/dist/commonjs/components/NetworkIcons.js +8 -1
- package/dist/commonjs/components/ReduxTreeView.d.ts +12 -3
- package/dist/commonjs/components/ReduxTreeView.js +1096 -278
- package/dist/commonjs/components/SectionHeader.d.ts +1 -1
- package/dist/commonjs/components/SectionHeader.js +7 -1
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/reduxLogger.d.ts +2 -0
- package/dist/commonjs/customHooks/reduxLogger.js +2 -0
- package/dist/commonjs/helpers/index.d.ts +1 -0
- package/dist/commonjs/helpers/index.js +15 -1
- package/dist/commonjs/helpers/settingsStore.d.ts +1 -0
- package/dist/commonjs/helpers/settingsStore.js +4 -0
- package/dist/commonjs/index.js +110 -91
- package/dist/commonjs/types/index.d.ts +3 -0
- package/dist/esm/components/AnalyticsDetail.js +64 -21
- package/dist/esm/components/HighlightText.js +3 -3
- package/dist/esm/components/JsonViewer.d.ts +3 -1
- package/dist/esm/components/JsonViewer.js +295 -10
- package/dist/esm/components/MetaAccordion.d.ts +10 -1
- package/dist/esm/components/MetaAccordion.js +90 -26
- package/dist/esm/components/NetworkIcons.d.ts +1 -0
- package/dist/esm/components/NetworkIcons.js +6 -0
- package/dist/esm/components/ReduxTreeView.d.ts +12 -3
- package/dist/esm/components/ReduxTreeView.js +1095 -279
- package/dist/esm/components/SectionHeader.d.ts +1 -1
- package/dist/esm/components/SectionHeader.js +8 -2
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/reduxLogger.d.ts +2 -0
- package/dist/esm/customHooks/reduxLogger.js +2 -0
- package/dist/esm/helpers/index.d.ts +1 -0
- package/dist/esm/helpers/index.js +14 -1
- package/dist/esm/helpers/settingsStore.d.ts +1 -0
- package/dist/esm/helpers/settingsStore.js +3 -0
- package/dist/esm/index.js +111 -92
- package/dist/esm/types/index.d.ts +3 -0
- package/package.json +1 -1
|
@@ -32,368 +32,1186 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.ReduxTreeView =
|
|
39
|
+
exports.ReduxTreeView = void 0;
|
|
37
40
|
const react_1 = __importStar(require("react"));
|
|
38
41
|
const react_native_1 = require("react-native");
|
|
39
42
|
const AppColors_1 = require("../styles/AppColors");
|
|
40
43
|
const AppFonts_1 = require("../styles/AppFonts");
|
|
41
44
|
const NetworkIcons_1 = require("./NetworkIcons");
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
const JsonViewer_1 = __importDefault(require("./JsonViewer"));
|
|
46
|
+
const DiffViewer_1 = __importDefault(require("./DiffViewer"));
|
|
47
|
+
const TouchableScale_1 = __importDefault(require("./TouchableScale"));
|
|
48
|
+
const helpers_1 = require("../helpers");
|
|
49
|
+
const settingsStore_1 = require("../helpers/settingsStore");
|
|
50
|
+
// Enable LayoutAnimation for Android
|
|
51
|
+
if (react_native_1.Platform.OS === 'android') {
|
|
52
|
+
react_native_1.UIManager.setLayoutAnimationEnabledExperimental?.(true);
|
|
53
|
+
}
|
|
54
|
+
const animateLayout = () => {
|
|
55
|
+
react_native_1.LayoutAnimation.configureNext(react_native_1.LayoutAnimation.Presets.easeInEaseOut);
|
|
56
|
+
};
|
|
57
|
+
// Chevron pointing left (for back buttons)
|
|
58
|
+
const BackChevronIcon = ({ color = AppColors_1.AppColors.purple, size = 12 }) => (<react_native_1.View style={{ transform: [{ rotate: '180deg' }], marginRight: 4 }}>
|
|
59
|
+
<NetworkIcons_1.ChevronIcon color={color} size={size}/>
|
|
60
|
+
</react_native_1.View>);
|
|
61
|
+
// Chevron pointing right (for list items)
|
|
62
|
+
const ForwardChevronIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12 }) => (<react_native_1.View style={{ transform: [{ rotate: '0deg' }], marginLeft: 'auto' }}>
|
|
63
|
+
<NetworkIcons_1.ChevronIcon color={color} size={size}/>
|
|
64
|
+
</react_native_1.View>);
|
|
65
|
+
// Helper: check if a value recursively contains a string term
|
|
66
|
+
const valueContainsTerm = (val, term) => {
|
|
67
|
+
if (!term)
|
|
68
|
+
return true;
|
|
69
|
+
const t = term.toLowerCase();
|
|
70
|
+
if (val === null || val === undefined)
|
|
71
|
+
return false;
|
|
72
|
+
if (typeof val !== 'object') {
|
|
73
|
+
return String(val).toLowerCase().includes(t);
|
|
53
74
|
}
|
|
75
|
+
if (Array.isArray(val)) {
|
|
76
|
+
return val.some(item => valueContainsTerm(item, term));
|
|
77
|
+
}
|
|
78
|
+
return Object.keys(val).some(key => key.toLowerCase().includes(t) || valueContainsTerm(val[key], term));
|
|
54
79
|
};
|
|
55
|
-
const
|
|
56
|
-
const
|
|
80
|
+
const ReduxTreeView = ({ state, actionHistory = [], lastActionMap = {}, search = '', onSearchChange, autoRefresh = true, onToggleAutoRefresh, onClearHistory, onDetailOpenChange, selectedSliceKey = null, onSelectSliceKey, selectedActionId = null, onSelectActionId, }) => {
|
|
81
|
+
const [activeTab, setActiveTab] = (0, react_1.useState)('state');
|
|
82
|
+
const [actionSubTab, setActionSubTab] = (0, react_1.useState)('payload');
|
|
83
|
+
// local fallbacks if props are not provided
|
|
84
|
+
const [localSliceKey, setLocalSliceKey] = (0, react_1.useState)(null);
|
|
85
|
+
const [localActionId, setLocalActionId] = (0, react_1.useState)(null);
|
|
86
|
+
const activeSliceKey = onSelectSliceKey ? selectedSliceKey : localSliceKey;
|
|
87
|
+
const activeActionId = onSelectActionId ? selectedActionId : localActionId;
|
|
88
|
+
const setActiveSliceKey = (key) => {
|
|
89
|
+
if (onSelectSliceKey)
|
|
90
|
+
onSelectSliceKey(key);
|
|
91
|
+
else
|
|
92
|
+
setLocalSliceKey(key);
|
|
93
|
+
};
|
|
94
|
+
const setActiveActionId = (id) => {
|
|
95
|
+
if (onSelectActionId)
|
|
96
|
+
onSelectActionId(id);
|
|
97
|
+
else
|
|
98
|
+
setLocalActionId(id);
|
|
99
|
+
};
|
|
100
|
+
// Expand / collapse all states for detail views
|
|
101
|
+
const [sliceForceOpen, setSliceForceOpen] = (0, react_1.useState)(undefined);
|
|
102
|
+
const [actionForceOpen, setActionForceOpen] = (0, react_1.useState)(undefined);
|
|
103
|
+
const [searchModeType, setSearchModeType] = (0, react_1.useState)(true);
|
|
104
|
+
const [searchModeData, setSearchModeData] = (0, react_1.useState)(true);
|
|
105
|
+
// Sorting directions
|
|
106
|
+
const [stateSortAsc, setStateSortAsc] = (0, react_1.useState)(true);
|
|
107
|
+
const [actionSortAsc, setActionSortAsc] = (0, react_1.useState)(false);
|
|
108
|
+
// Persistence-related states for State Slice details
|
|
109
|
+
const [sliceDetailTab, setSliceDetailTab] = (0, react_1.useState)('live');
|
|
110
|
+
const [isPersisted, setIsPersisted] = (0, react_1.useState)(false);
|
|
111
|
+
const [persistedData, setPersistedData] = (0, react_1.useState)(null);
|
|
57
112
|
(0, react_1.useEffect)(() => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}, [expanded, progress]);
|
|
64
|
-
const rotate = progress.interpolate({
|
|
65
|
-
inputRange: [0, 1],
|
|
66
|
-
outputRange: ['0deg', '90deg'],
|
|
67
|
-
});
|
|
68
|
-
return (<react_native_1.Animated.View style={[style, { transform: [{ rotate }] }]}>
|
|
69
|
-
<NetworkIcons_1.ChevronIcon color={color} size={size}/>
|
|
70
|
-
</react_native_1.Animated.View>);
|
|
71
|
-
};
|
|
72
|
-
const ReduxValueNode = ({ name, value, level, search, lastAction }) => {
|
|
73
|
-
const [expanded, setExpanded] = (0, react_1.useState)(level < 1);
|
|
74
|
-
const isObject = typeof value === 'object' && value !== null;
|
|
75
|
-
const isArray = Array.isArray(value);
|
|
76
|
-
const nameStr = String(name);
|
|
77
|
-
// Filter check if search query matches key or value
|
|
78
|
-
const matchesSearch = (k, val) => {
|
|
79
|
-
if (!search)
|
|
80
|
-
return true;
|
|
81
|
-
const s = search.toLowerCase();
|
|
82
|
-
if (k.toLowerCase().includes(s))
|
|
83
|
-
return true;
|
|
84
|
-
if (typeof val !== 'object' && String(val).toLowerCase().includes(s))
|
|
85
|
-
return true;
|
|
86
|
-
if (typeof val === 'object' && val !== null) {
|
|
87
|
-
return Object.keys(val).some(key => matchesSearch(key, val[key]));
|
|
113
|
+
if (activeSliceKey === null) {
|
|
114
|
+
setIsPersisted(false);
|
|
115
|
+
setPersistedData(null);
|
|
116
|
+
setSliceDetailTab('live');
|
|
117
|
+
return;
|
|
88
118
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
119
|
+
async function checkPersistence() {
|
|
120
|
+
try {
|
|
121
|
+
const storage = (0, settingsStore_1.getCustomStorage)();
|
|
122
|
+
if (!storage) {
|
|
123
|
+
setIsPersisted(false);
|
|
124
|
+
setPersistedData(null);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
// Check direct key: persist:sliceKey
|
|
128
|
+
let raw = await storage.getItem(`persist:${activeSliceKey}`);
|
|
129
|
+
if (raw) {
|
|
130
|
+
try {
|
|
131
|
+
setPersistedData(JSON.parse(raw));
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
setPersistedData(raw);
|
|
135
|
+
}
|
|
136
|
+
setIsPersisted(true);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
// Check root key: persist:root
|
|
140
|
+
let rootRaw = await storage.getItem('persist:root');
|
|
141
|
+
if (rootRaw) {
|
|
142
|
+
const parsedRoot = JSON.parse(rootRaw);
|
|
143
|
+
if (parsedRoot && parsedRoot[activeSliceKey] !== undefined) {
|
|
144
|
+
const nested = parsedRoot[activeSliceKey];
|
|
145
|
+
try {
|
|
146
|
+
setPersistedData(typeof nested === 'string' ? JSON.parse(nested) : nested);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
setPersistedData(nested);
|
|
150
|
+
}
|
|
151
|
+
setIsPersisted(true);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
console.log('Error checking Redux persistence:', e);
|
|
158
|
+
}
|
|
159
|
+
setIsPersisted(false);
|
|
160
|
+
setPersistedData(null);
|
|
103
161
|
}
|
|
104
|
-
|
|
105
|
-
|
|
162
|
+
checkPersistence();
|
|
163
|
+
}, [activeSliceKey]);
|
|
164
|
+
const handleClearPersistence = () => {
|
|
165
|
+
react_native_1.Alert.alert('Clear Persisted State', `Are you sure you want to delete the persisted storage item for the slice "${activeSliceKey}"? This will clear the value from device storage, but the current active in-memory Redux state will remain unchanged until the next app reload.`, [
|
|
166
|
+
{ text: 'Cancel', style: 'cancel' },
|
|
167
|
+
{
|
|
168
|
+
text: 'Delete',
|
|
169
|
+
style: 'destructive',
|
|
170
|
+
onPress: async () => {
|
|
171
|
+
try {
|
|
172
|
+
const storage = (0, settingsStore_1.getCustomStorage)();
|
|
173
|
+
if (!storage)
|
|
174
|
+
return;
|
|
175
|
+
// Delete direct key
|
|
176
|
+
if (typeof storage.removeItem === 'function') {
|
|
177
|
+
await storage.removeItem(`persist:${activeSliceKey}`);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
await storage.setItem(`persist:${activeSliceKey}`, '');
|
|
181
|
+
}
|
|
182
|
+
// Delete from root key
|
|
183
|
+
let rootRaw = await storage.getItem('persist:root');
|
|
184
|
+
if (rootRaw) {
|
|
185
|
+
const parsed = JSON.parse(rootRaw);
|
|
186
|
+
if (parsed && parsed[activeSliceKey] !== undefined) {
|
|
187
|
+
delete parsed[activeSliceKey];
|
|
188
|
+
await storage.setItem('persist:root', JSON.stringify(parsed));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
setIsPersisted(false);
|
|
192
|
+
setPersistedData(null);
|
|
193
|
+
setSliceDetailTab('live');
|
|
194
|
+
if (react_native_1.Platform.OS === 'android') {
|
|
195
|
+
react_native_1.ToastAndroid.show('Persisted state cleared', react_native_1.ToastAndroid.SHORT);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
react_native_1.Alert.alert('Cleared', 'Persisted state has been cleared from device storage.');
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
react_native_1.Alert.alert('Error', 'Failed to clear persisted state.');
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
]);
|
|
207
|
+
};
|
|
208
|
+
const isSearching = search.trim().length > 0;
|
|
209
|
+
(0, react_1.useEffect)(() => {
|
|
210
|
+
onDetailOpenChange?.(activeSliceKey !== null || activeActionId !== null);
|
|
211
|
+
return () => {
|
|
212
|
+
onDetailOpenChange?.(false);
|
|
213
|
+
};
|
|
214
|
+
}, [activeSliceKey, activeActionId, onDetailOpenChange]);
|
|
215
|
+
// Reset details view when tab changes
|
|
216
|
+
const switchTab = (tab) => {
|
|
217
|
+
animateLayout();
|
|
218
|
+
setActiveTab(tab);
|
|
219
|
+
setActiveSliceKey(null);
|
|
220
|
+
setActiveActionId(null);
|
|
221
|
+
setSliceForceOpen(undefined);
|
|
222
|
+
setActionForceOpen(undefined);
|
|
223
|
+
};
|
|
224
|
+
const handleGoBackSlice = () => {
|
|
225
|
+
animateLayout();
|
|
226
|
+
setActiveSliceKey(null);
|
|
227
|
+
setSliceForceOpen(undefined);
|
|
228
|
+
};
|
|
229
|
+
const handleGoBackAction = () => {
|
|
230
|
+
animateLayout();
|
|
231
|
+
setActiveActionId(null);
|
|
232
|
+
setActionForceOpen(undefined);
|
|
233
|
+
};
|
|
234
|
+
// Filtered state keys based on search query
|
|
235
|
+
const filteredStateKeys = (0, react_1.useMemo)(() => {
|
|
236
|
+
if (!state || typeof state !== 'object')
|
|
237
|
+
return [];
|
|
238
|
+
const keys = Object.keys(state);
|
|
239
|
+
let result = keys;
|
|
240
|
+
if (isSearching) {
|
|
241
|
+
result = keys.filter(key => {
|
|
242
|
+
const typeMatch = searchModeType && key.toLowerCase().includes(search.toLowerCase());
|
|
243
|
+
const dataMatch = searchModeData && valueContainsTerm(state[key], search);
|
|
244
|
+
return typeMatch || dataMatch;
|
|
245
|
+
});
|
|
106
246
|
}
|
|
107
|
-
|
|
108
|
-
|
|
247
|
+
return [...result].sort((a, b) => {
|
|
248
|
+
const comparison = a.localeCompare(b);
|
|
249
|
+
return stateSortAsc ? comparison : -comparison;
|
|
250
|
+
});
|
|
251
|
+
}, [state, search, isSearching, searchModeType, searchModeData, stateSortAsc]);
|
|
252
|
+
// Filtered action history based on search query
|
|
253
|
+
const filteredActionHistory = (0, react_1.useMemo)(() => {
|
|
254
|
+
if (!actionHistory)
|
|
255
|
+
return [];
|
|
256
|
+
let result = actionHistory;
|
|
257
|
+
if (isSearching) {
|
|
258
|
+
result = actionHistory.filter(action => {
|
|
259
|
+
const typeMatch = searchModeType && action.type.toLowerCase().includes(search.toLowerCase());
|
|
260
|
+
const payloadMatch = searchModeData && action.payload && valueContainsTerm(action.payload, search);
|
|
261
|
+
return typeMatch || payloadMatch;
|
|
262
|
+
});
|
|
109
263
|
}
|
|
110
|
-
return
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
264
|
+
return [...result].sort((a, b) => {
|
|
265
|
+
const comparison = a.id - b.id;
|
|
266
|
+
return actionSortAsc ? comparison : -comparison;
|
|
267
|
+
});
|
|
268
|
+
}, [actionHistory, search, isSearching, searchModeType, searchModeData, actionSortAsc]);
|
|
269
|
+
// Find currently selected action object
|
|
270
|
+
const selectedAction = (0, react_1.useMemo)(() => {
|
|
271
|
+
if (activeActionId === null)
|
|
272
|
+
return null;
|
|
273
|
+
return actionHistory.find(a => a.id === activeActionId) || null;
|
|
274
|
+
}, [activeActionId, actionHistory]);
|
|
275
|
+
if (!state || typeof state !== 'object') {
|
|
276
|
+
return (<react_native_1.View style={styles.errorContainer}>
|
|
277
|
+
<react_native_1.Text style={styles.errorText}>No connected Redux store state found.</react_native_1.Text>
|
|
278
|
+
</react_native_1.View>);
|
|
279
|
+
}
|
|
280
|
+
// ── Render Detail View: State Slice ──
|
|
281
|
+
if (activeTab === 'state' && activeSliceKey !== null) {
|
|
282
|
+
const sliceData = state[activeSliceKey];
|
|
283
|
+
const fieldsCount = typeof sliceData === 'object' && sliceData !== null
|
|
284
|
+
? Object.keys(sliceData).length
|
|
285
|
+
: 1;
|
|
286
|
+
return (<react_native_1.View style={{ flex: 1 }}>
|
|
287
|
+
{/* Non-scrollable header */}
|
|
288
|
+
<react_native_1.View style={{ paddingHorizontal: 6, paddingTop: 4 }}>
|
|
289
|
+
<react_native_1.View style={styles.apiLikeInfoBar}>
|
|
290
|
+
<react_native_1.View style={styles.apiBadgeRow}>
|
|
291
|
+
<react_native_1.View style={[styles.apiMethodBadge, { backgroundColor: AppColors_1.AppColors.purple }]}>
|
|
292
|
+
<react_native_1.Text style={styles.apiMethodBadgeText}>REDUX</react_native_1.Text>
|
|
293
|
+
</react_native_1.View>
|
|
294
|
+
<react_native_1.View style={[styles.apiMethodBadge, { backgroundColor: AppColors_1.AppColors.purpleShade50, borderWidth: 1, borderColor: AppColors_1.AppColors.purple + '30' }]}>
|
|
295
|
+
<react_native_1.Text style={[styles.apiMethodBadgeText, { color: AppColors_1.AppColors.purple }]}>SLICE</react_native_1.Text>
|
|
296
|
+
</react_native_1.View>
|
|
297
|
+
{isPersisted && (<react_native_1.View style={[styles.apiMethodBadge, { backgroundColor: '#10B981' }]}>
|
|
298
|
+
<react_native_1.Text style={styles.apiMethodBadgeText}>PERSISTED</react_native_1.Text>
|
|
299
|
+
</react_native_1.View>)}
|
|
300
|
+
<react_native_1.View style={styles.apiChip}>
|
|
301
|
+
<react_native_1.Text style={styles.apiChipText}>{(0, helpers_1.getSize)(sliceData)}</react_native_1.Text>
|
|
302
|
+
</react_native_1.View>
|
|
303
|
+
<react_native_1.View style={styles.apiChip}>
|
|
304
|
+
<react_native_1.Text style={styles.apiChipText}>{fieldsCount} {fieldsCount === 1 ? 'field' : 'fields'}</react_native_1.Text>
|
|
305
|
+
</react_native_1.View>
|
|
306
|
+
</react_native_1.View>
|
|
307
|
+
|
|
308
|
+
<react_native_1.Text style={styles.apiTitleText} selectable={true}>{activeSliceKey}</react_native_1.Text>
|
|
309
|
+
|
|
310
|
+
<react_native_1.View style={styles.apiMetaRow}>
|
|
311
|
+
<NetworkIcons_1.ClockIcon color={AppColors_1.AppColors.grayTextWeak} size={10}/>
|
|
312
|
+
<react_native_1.Text style={styles.apiMetaText}>
|
|
313
|
+
Last updated: {lastActionMap[activeSliceKey] ? lastActionMap[activeSliceKey].timestamp : 'Initial'}
|
|
123
314
|
</react_native_1.Text>
|
|
124
|
-
</react_native_1.View>
|
|
315
|
+
</react_native_1.View>
|
|
316
|
+
</react_native_1.View>
|
|
317
|
+
</react_native_1.View>
|
|
318
|
+
|
|
319
|
+
{/* Segment Control */}
|
|
320
|
+
<react_native_1.View style={{
|
|
321
|
+
flexDirection: 'row',
|
|
322
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
323
|
+
borderRadius: 10,
|
|
324
|
+
padding: 3,
|
|
325
|
+
marginHorizontal: 6,
|
|
326
|
+
marginBottom: 10,
|
|
327
|
+
marginTop: 6,
|
|
328
|
+
borderWidth: 1,
|
|
329
|
+
borderColor: AppColors_1.AppColors.grayBorderSecondary,
|
|
330
|
+
}}>
|
|
331
|
+
{(isPersisted ? ['live', 'persisted'] : ['live']).map(tab => {
|
|
332
|
+
const isActive = sliceDetailTab === tab;
|
|
333
|
+
const getLabel = () => {
|
|
334
|
+
if (tab === 'live')
|
|
335
|
+
return 'Live State';
|
|
336
|
+
return `Persisted (${(0, helpers_1.getSize)(persistedData)})`;
|
|
337
|
+
};
|
|
338
|
+
const getIcon = () => {
|
|
339
|
+
const iconColor = isActive ? '#FFFFFF' : AppColors_1.AppColors.grayText;
|
|
340
|
+
if (tab === 'live')
|
|
341
|
+
return <NetworkIcons_1.LayersIcon color={iconColor} size={11}/>;
|
|
342
|
+
return <NetworkIcons_1.CalendarIcon color={iconColor} size={11}/>;
|
|
343
|
+
};
|
|
344
|
+
return (<react_native_1.Pressable key={tab} onPress={() => {
|
|
345
|
+
animateLayout();
|
|
346
|
+
setSliceDetailTab(tab);
|
|
347
|
+
}} style={{
|
|
348
|
+
flex: 1,
|
|
349
|
+
paddingVertical: 6,
|
|
350
|
+
flexDirection: 'row',
|
|
351
|
+
alignItems: 'center',
|
|
352
|
+
justifyContent: 'center',
|
|
353
|
+
borderRadius: 8,
|
|
354
|
+
backgroundColor: isActive ? AppColors_1.AppColors.purple : 'transparent',
|
|
355
|
+
gap: 4,
|
|
356
|
+
}}>
|
|
357
|
+
{getIcon()}
|
|
358
|
+
<react_native_1.Text style={{
|
|
359
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
360
|
+
fontSize: 10,
|
|
361
|
+
color: isActive ? '#FFFFFF' : AppColors_1.AppColors.grayText,
|
|
362
|
+
}}>
|
|
363
|
+
{getLabel()}
|
|
364
|
+
</react_native_1.Text>
|
|
365
|
+
</react_native_1.Pressable>);
|
|
366
|
+
})}
|
|
367
|
+
</react_native_1.View>
|
|
368
|
+
|
|
369
|
+
{/* Scrollable Tab Content */}
|
|
370
|
+
<react_native_1.View style={{ flex: 1, paddingHorizontal: 6 }}>
|
|
371
|
+
{/* Back button + controls */}
|
|
372
|
+
<react_native_1.View style={styles.contentDetailSubHeader}>
|
|
373
|
+
<TouchableScale_1.default onPress={handleGoBackSlice} style={styles.backBtn} hitSlop={12}>
|
|
374
|
+
<BackChevronIcon color={AppColors_1.AppColors.purple} size={11}/>
|
|
375
|
+
<react_native_1.Text style={styles.backBtnText}>State Slices</react_native_1.Text>
|
|
376
|
+
</TouchableScale_1.default>
|
|
377
|
+
|
|
378
|
+
<react_native_1.View style={styles.detailHeaderActions}>
|
|
379
|
+
{isPersisted && sliceDetailTab === 'persisted' && (<TouchableScale_1.default onPress={handleClearPersistence} style={[styles.detailHeaderBtn, { marginRight: 8 }]} hitSlop={8}>
|
|
380
|
+
<NetworkIcons_1.TrashIcon color={AppColors_1.AppColors.errorColor} size={14}/>
|
|
381
|
+
</TouchableScale_1.default>)}
|
|
382
|
+
|
|
383
|
+
<TouchableScale_1.default onPress={() => {
|
|
384
|
+
animateLayout();
|
|
385
|
+
setSliceForceOpen(prev => (prev === true ? false : prev === false ? undefined : true));
|
|
386
|
+
}} style={styles.detailHeaderBtn} hitSlop={8}>
|
|
387
|
+
<NetworkIcons_1.ExpandCollapseIcon expanded={sliceForceOpen !== false} color={AppColors_1.AppColors.purple} size={14}/>
|
|
388
|
+
</TouchableScale_1.default>
|
|
389
|
+
|
|
390
|
+
<TouchableScale_1.default onPress={() => {
|
|
391
|
+
const dataToCopy = sliceDetailTab === 'live' ? sliceData : persistedData;
|
|
392
|
+
(0, helpers_1.copyToClipboard)(dataToCopy, `Redux Slice '${activeSliceKey}' (${sliceDetailTab})`);
|
|
393
|
+
}} style={styles.detailHeaderBtn} hitSlop={8}>
|
|
394
|
+
<NetworkIcons_1.CopyIcon color={AppColors_1.AppColors.purple} size={14}/>
|
|
395
|
+
</TouchableScale_1.default>
|
|
396
|
+
</react_native_1.View>
|
|
397
|
+
</react_native_1.View>
|
|
398
|
+
|
|
399
|
+
<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingBottom: 24 }} showsVerticalScrollIndicator={true}>
|
|
400
|
+
<react_native_1.View style={{ padding: 12 }}>
|
|
401
|
+
<JsonViewer_1.default data={sliceDetailTab === 'live' ? sliceData : (persistedData ?? 'No persisted data')} search={search} forceOpen={sliceForceOpen !== undefined ? sliceForceOpen : (isSearching ? true : undefined)} fullHeight={true}/>
|
|
402
|
+
</react_native_1.View>
|
|
403
|
+
</react_native_1.ScrollView>
|
|
125
404
|
</react_native_1.View>
|
|
126
405
|
</react_native_1.View>);
|
|
127
406
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
407
|
+
// ── Render Detail View: Timeline Action ──
|
|
408
|
+
if (activeTab === 'timeline' && selectedAction !== null) {
|
|
409
|
+
const affectedSlices = selectedAction.affectedSlices || [];
|
|
410
|
+
return (<react_native_1.View style={{ flex: 1 }}>
|
|
411
|
+
{/* Non-scrollable header */}
|
|
412
|
+
<react_native_1.View style={{ paddingHorizontal: 6, paddingTop: 4 }}>
|
|
413
|
+
<react_native_1.View style={styles.apiLikeInfoBar}>
|
|
414
|
+
<react_native_1.View style={styles.apiBadgeRow}>
|
|
415
|
+
<react_native_1.View style={[styles.apiMethodBadge, { backgroundColor: AppColors_1.AppColors.purple }]}>
|
|
416
|
+
<react_native_1.Text style={styles.apiMethodBadgeText}>REDUX</react_native_1.Text>
|
|
417
|
+
</react_native_1.View>
|
|
418
|
+
<react_native_1.View style={[styles.apiMethodBadge, { backgroundColor: '#F59E0B' }]}>
|
|
419
|
+
<react_native_1.Text style={styles.apiMethodBadgeText}>ACTION</react_native_1.Text>
|
|
420
|
+
</react_native_1.View>
|
|
421
|
+
<react_native_1.View style={styles.apiChip}>
|
|
422
|
+
<react_native_1.Text style={styles.apiChipText}>#{selectedAction.id}</react_native_1.Text>
|
|
423
|
+
</react_native_1.View>
|
|
424
|
+
<react_native_1.View style={styles.apiChip}>
|
|
425
|
+
<react_native_1.Text style={styles.apiChipText}>{(0, helpers_1.getSize)(selectedAction.payload)}</react_native_1.Text>
|
|
426
|
+
</react_native_1.View>
|
|
427
|
+
</react_native_1.View>
|
|
428
|
+
|
|
429
|
+
<react_native_1.Text style={styles.apiTitleText} selectable={true}>{selectedAction.type}</react_native_1.Text>
|
|
430
|
+
|
|
431
|
+
<react_native_1.View style={styles.apiMetaRow}>
|
|
432
|
+
<NetworkIcons_1.ClockIcon color={AppColors_1.AppColors.grayTextWeak} size={10}/>
|
|
433
|
+
<react_native_1.Text style={styles.apiMetaText}>Dispatched: {selectedAction.timestamp}</react_native_1.Text>
|
|
434
|
+
</react_native_1.View>
|
|
435
|
+
</react_native_1.View>
|
|
150
436
|
</react_native_1.View>
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
437
|
+
|
|
438
|
+
{/* Affected Slices Tags list */}
|
|
439
|
+
{affectedSlices.length > 0 && (<react_native_1.View style={styles.detailAffectedTags}>
|
|
440
|
+
<react_native_1.Text style={styles.affectedTagsLabel}>AFFECTED SLICES:</react_native_1.Text>
|
|
441
|
+
<react_native_1.View style={styles.detailTagsList}>
|
|
442
|
+
{affectedSlices.map(slice => (<react_native_1.View key={slice} style={styles.sliceTag}>
|
|
443
|
+
<react_native_1.Text style={styles.sliceTagText}>{slice}</react_native_1.Text>
|
|
444
|
+
</react_native_1.View>))}
|
|
445
|
+
</react_native_1.View>
|
|
446
|
+
</react_native_1.View>)}
|
|
447
|
+
|
|
448
|
+
{/* Segment Control */}
|
|
449
|
+
<react_native_1.View style={{
|
|
450
|
+
flexDirection: 'row',
|
|
451
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
452
|
+
borderRadius: 10,
|
|
453
|
+
padding: 3,
|
|
454
|
+
marginHorizontal: 6,
|
|
455
|
+
marginBottom: 10,
|
|
456
|
+
marginTop: 6,
|
|
457
|
+
borderWidth: 1,
|
|
458
|
+
borderColor: AppColors_1.AppColors.grayBorderSecondary,
|
|
171
459
|
}}>
|
|
172
|
-
|
|
173
|
-
|
|
460
|
+
{['payload', 'diff', 'state'].map(tab => {
|
|
461
|
+
const isActive = actionSubTab === tab;
|
|
462
|
+
const getLabel = () => {
|
|
463
|
+
if (tab === 'payload')
|
|
464
|
+
return 'Payload';
|
|
465
|
+
if (tab === 'diff')
|
|
466
|
+
return 'Diff Changes';
|
|
467
|
+
return 'Snapshot';
|
|
468
|
+
};
|
|
469
|
+
const getIcon = () => {
|
|
470
|
+
const iconColor = isActive ? '#FFFFFF' : AppColors_1.AppColors.grayText;
|
|
471
|
+
if (tab === 'payload')
|
|
472
|
+
return <NetworkIcons_1.RequestIcon color={iconColor} size={11}/>;
|
|
473
|
+
if (tab === 'diff')
|
|
474
|
+
return <NetworkIcons_1.DiffIcon color={iconColor} size={11}/>;
|
|
475
|
+
return <NetworkIcons_1.LayersIcon color={iconColor} size={11}/>;
|
|
476
|
+
};
|
|
477
|
+
return (<react_native_1.Pressable key={tab} onPress={() => {
|
|
478
|
+
animateLayout();
|
|
479
|
+
setActionSubTab(tab);
|
|
480
|
+
}} style={{
|
|
481
|
+
flex: 1,
|
|
482
|
+
paddingVertical: 6,
|
|
483
|
+
flexDirection: 'row',
|
|
484
|
+
alignItems: 'center',
|
|
485
|
+
justifyContent: 'center',
|
|
486
|
+
borderRadius: 8,
|
|
487
|
+
backgroundColor: isActive ? AppColors_1.AppColors.purple : 'transparent',
|
|
488
|
+
gap: 4,
|
|
489
|
+
}}>
|
|
490
|
+
{getIcon()}
|
|
491
|
+
<react_native_1.Text style={{
|
|
492
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
493
|
+
fontSize: 10,
|
|
494
|
+
color: isActive ? '#FFFFFF' : AppColors_1.AppColors.grayText,
|
|
495
|
+
}}>
|
|
496
|
+
{getLabel()}
|
|
497
|
+
</react_native_1.Text>
|
|
498
|
+
</react_native_1.Pressable>);
|
|
499
|
+
})}
|
|
500
|
+
</react_native_1.View>
|
|
501
|
+
|
|
502
|
+
{/* Scrollable Tab Content */}
|
|
503
|
+
<react_native_1.View style={{ flex: 1, paddingHorizontal: 6 }}>
|
|
504
|
+
{/* Back button + controls */}
|
|
505
|
+
<react_native_1.View style={styles.contentDetailSubHeader}>
|
|
506
|
+
<TouchableScale_1.default onPress={handleGoBackAction} style={styles.backBtn} hitSlop={12}>
|
|
507
|
+
<BackChevronIcon color={AppColors_1.AppColors.purple} size={11}/>
|
|
508
|
+
<react_native_1.Text style={styles.backBtnText}>Actions</react_native_1.Text>
|
|
509
|
+
</TouchableScale_1.default>
|
|
510
|
+
|
|
511
|
+
{(actionSubTab === 'payload' || actionSubTab === 'state') && (<react_native_1.View style={styles.detailHeaderActions}>
|
|
512
|
+
<TouchableScale_1.default onPress={() => {
|
|
513
|
+
animateLayout();
|
|
514
|
+
setActionForceOpen(prev => (prev === true ? false : prev === false ? undefined : true));
|
|
515
|
+
}} style={styles.detailHeaderBtn} hitSlop={8}>
|
|
516
|
+
<NetworkIcons_1.ExpandCollapseIcon expanded={actionForceOpen !== false} color={AppColors_1.AppColors.purple} size={14}/>
|
|
517
|
+
</TouchableScale_1.default>
|
|
518
|
+
|
|
519
|
+
<TouchableScale_1.default onPress={() => {
|
|
520
|
+
const dataToCopy = actionSubTab === 'payload' ? selectedAction.payload : selectedAction.nextState;
|
|
521
|
+
(0, helpers_1.copyToClipboard)(dataToCopy, actionSubTab === 'payload' ? 'Action payload' : 'State snapshot');
|
|
522
|
+
}} style={styles.detailHeaderBtn} hitSlop={8}>
|
|
523
|
+
<NetworkIcons_1.CopyIcon color={AppColors_1.AppColors.purple} size={14}/>
|
|
524
|
+
</TouchableScale_1.default>
|
|
525
|
+
</react_native_1.View>)}
|
|
526
|
+
</react_native_1.View>
|
|
527
|
+
|
|
528
|
+
<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingBottom: 24 }} showsVerticalScrollIndicator={true}>
|
|
529
|
+
{actionSubTab === 'payload' && (<react_native_1.View style={{ padding: 12 }}>
|
|
530
|
+
<JsonViewer_1.default data={selectedAction.payload ?? 'No payload data'} wrap forceOpen={actionForceOpen !== undefined ? actionForceOpen : undefined} fullHeight={true}/>
|
|
531
|
+
</react_native_1.View>)}
|
|
532
|
+
|
|
533
|
+
{actionSubTab === 'diff' && (<react_native_1.View style={{ padding: 12 }}>
|
|
534
|
+
<DiffViewer_1.default oldData={selectedAction.prevState} newData={selectedAction.nextState}/>
|
|
535
|
+
</react_native_1.View>)}
|
|
536
|
+
|
|
537
|
+
{actionSubTab === 'state' && (<react_native_1.View style={{ padding: 12 }}>
|
|
538
|
+
<JsonViewer_1.default data={selectedAction.nextState} wrap forceOpen={actionForceOpen !== undefined ? actionForceOpen : undefined} fullHeight={true}/>
|
|
539
|
+
</react_native_1.View>)}
|
|
540
|
+
</react_native_1.ScrollView>
|
|
541
|
+
</react_native_1.View>
|
|
542
|
+
</react_native_1.View>);
|
|
174
543
|
}
|
|
175
|
-
|
|
176
|
-
const toggleReducer = (key) => {
|
|
177
|
-
animateTreeLayout();
|
|
178
|
-
setReducerExpanded(prev => ({
|
|
179
|
-
...prev,
|
|
180
|
-
[key]: !prev[key],
|
|
181
|
-
}));
|
|
182
|
-
};
|
|
544
|
+
// ── Render List Views (Default) ──
|
|
183
545
|
return (<react_native_1.View style={styles.container}>
|
|
184
|
-
{/*
|
|
185
|
-
<react_native_1.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
546
|
+
{/* ── Control Bar ── */}
|
|
547
|
+
<react_native_1.View style={styles.toolbar}>
|
|
548
|
+
<react_native_1.View style={styles.statusSection}>
|
|
549
|
+
<react_native_1.View style={[styles.statusBadge, autoRefresh ? styles.statusBadgeActive : styles.statusBadgePaused]}>
|
|
550
|
+
<react_native_1.View style={[styles.statusDot, autoRefresh ? styles.statusDotActive : styles.statusDotPaused]}/>
|
|
551
|
+
<react_native_1.Text style={[styles.statusBadgeText, autoRefresh ? styles.statusTextActive : styles.statusTextPaused]}>
|
|
552
|
+
{autoRefresh ? 'LIVE' : 'PAUSED'}
|
|
553
|
+
</react_native_1.Text>
|
|
554
|
+
</react_native_1.View>
|
|
193
555
|
</react_native_1.View>
|
|
194
|
-
|
|
195
|
-
|
|
556
|
+
|
|
557
|
+
<react_native_1.View style={styles.toolbarActions}>
|
|
558
|
+
{/* Sorting Toggle Button */}
|
|
559
|
+
<TouchableScale_1.default onPress={() => {
|
|
560
|
+
animateLayout();
|
|
561
|
+
if (activeTab === 'state') {
|
|
562
|
+
setStateSortAsc(prev => !prev);
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
setActionSortAsc(prev => !prev);
|
|
566
|
+
}
|
|
567
|
+
}} style={styles.iconBtn} hitSlop={8}>
|
|
568
|
+
<NetworkIcons_1.SortIcon ascending={activeTab === 'state' ? stateSortAsc : actionSortAsc} color={AppColors_1.AppColors.purple} size={15}/>
|
|
569
|
+
</TouchableScale_1.default>
|
|
570
|
+
|
|
571
|
+
{onToggleAutoRefresh && (<TouchableScale_1.default onPress={onToggleAutoRefresh} style={styles.iconBtn} hitSlop={8}>
|
|
572
|
+
<NetworkIcons_1.HeaderPauseIcon isPaused={!autoRefresh} color={AppColors_1.AppColors.purple} size={15}/>
|
|
573
|
+
</TouchableScale_1.default>)}
|
|
574
|
+
{onClearHistory && (<TouchableScale_1.default onPress={onClearHistory} style={[styles.iconBtn, { borderColor: AppColors_1.AppColors.errorColor + '40', backgroundColor: AppColors_1.AppColors.errorColor + '08' }]} hitSlop={8}>
|
|
575
|
+
<NetworkIcons_1.TrashIcon color={AppColors_1.AppColors.errorColor} size={15}/>
|
|
576
|
+
</TouchableScale_1.default>)}
|
|
196
577
|
</react_native_1.View>
|
|
197
|
-
</react_native_1.
|
|
578
|
+
</react_native_1.View>
|
|
579
|
+
|
|
580
|
+
{/* ── Search Bar ── */}
|
|
581
|
+
{onSearchChange && (<react_native_1.View style={styles.searchContainer}>
|
|
582
|
+
<react_native_1.View style={styles.searchBar}>
|
|
583
|
+
<NetworkIcons_1.SearchIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
|
|
584
|
+
<react_native_1.TextInput placeholder="Search keys, values, or action payloads..." placeholderTextColor={AppColors_1.AppColors.grayTextWeak} value={search} onChangeText={onSearchChange} style={styles.searchInput} autoCorrect={false} autoCapitalize="none"/>
|
|
585
|
+
{search.length > 0 && (<TouchableScale_1.default onPress={() => onSearchChange('')} hitSlop={10}>
|
|
586
|
+
<NetworkIcons_1.ClearIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
|
|
587
|
+
</TouchableScale_1.default>)}
|
|
588
|
+
</react_native_1.View>
|
|
589
|
+
<react_native_1.View style={styles.filterChipRow}>
|
|
590
|
+
<react_native_1.Text style={styles.filterChipLabel}>FILTER BY:</react_native_1.Text>
|
|
591
|
+
<react_native_1.Pressable onPress={() => {
|
|
592
|
+
animateLayout();
|
|
593
|
+
if (searchModeType && !searchModeData)
|
|
594
|
+
return; // Prevent disabling both
|
|
595
|
+
setSearchModeType(!searchModeType);
|
|
596
|
+
}} style={[styles.filterChip, searchModeType && styles.filterChipActive]}>
|
|
597
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
|
|
598
|
+
<NetworkIcons_1.SignalIcon color={searchModeType ? AppColors_1.AppColors.purple : AppColors_1.AppColors.grayText} size={11}/>
|
|
599
|
+
<react_native_1.Text style={[styles.filterChipText, searchModeType && styles.filterChipTextActive]}>
|
|
600
|
+
Type / Key
|
|
601
|
+
</react_native_1.Text>
|
|
602
|
+
</react_native_1.View>
|
|
603
|
+
</react_native_1.Pressable>
|
|
604
|
+
<react_native_1.Pressable onPress={() => {
|
|
605
|
+
animateLayout();
|
|
606
|
+
if (!searchModeType && searchModeData)
|
|
607
|
+
return; // Prevent disabling both
|
|
608
|
+
setSearchModeData(!searchModeData);
|
|
609
|
+
}} style={[styles.filterChip, searchModeData && styles.filterChipActive]}>
|
|
610
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
|
|
611
|
+
<NetworkIcons_1.LayersIcon color={searchModeData ? AppColors_1.AppColors.purple : AppColors_1.AppColors.grayText} size={11}/>
|
|
612
|
+
<react_native_1.Text style={[styles.filterChipText, searchModeData && styles.filterChipTextActive]}>
|
|
613
|
+
Payload Data
|
|
614
|
+
</react_native_1.Text>
|
|
615
|
+
</react_native_1.View>
|
|
616
|
+
</react_native_1.Pressable>
|
|
617
|
+
</react_native_1.View>
|
|
618
|
+
</react_native_1.View>)}
|
|
619
|
+
|
|
620
|
+
{/* ── Tab Selector ── */}
|
|
621
|
+
<react_native_1.View style={styles.tabContainer}>
|
|
622
|
+
<react_native_1.Pressable style={[styles.tabButton, activeTab === 'state' && styles.tabButtonActive]} onPress={() => switchTab('state')}>
|
|
623
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
624
|
+
<NetworkIcons_1.LayersIcon color={activeTab === 'state' ? AppColors_1.AppColors.purple : AppColors_1.AppColors.grayText} size={12}/>
|
|
625
|
+
<react_native_1.Text style={[styles.tabButtonText, activeTab === 'state' && styles.tabButtonTextActive]}>
|
|
626
|
+
State Slices ({filteredStateKeys.length})
|
|
627
|
+
</react_native_1.Text>
|
|
628
|
+
</react_native_1.View>
|
|
629
|
+
</react_native_1.Pressable>
|
|
630
|
+
<react_native_1.Pressable style={[styles.tabButton, activeTab === 'timeline' && styles.tabButtonActive]} onPress={() => switchTab('timeline')}>
|
|
631
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
632
|
+
<NetworkIcons_1.TerminalIcon color={activeTab === 'timeline' ? AppColors_1.AppColors.purple : AppColors_1.AppColors.grayText} size={12}/>
|
|
633
|
+
<react_native_1.Text style={[styles.tabButtonText, activeTab === 'timeline' && styles.tabButtonTextActive]}>
|
|
634
|
+
Actions ({filteredActionHistory.length})
|
|
635
|
+
</react_native_1.Text>
|
|
636
|
+
</react_native_1.View>
|
|
637
|
+
</react_native_1.Pressable>
|
|
638
|
+
</react_native_1.View>
|
|
198
639
|
|
|
199
|
-
{
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
640
|
+
{/* ── State List View ── */}
|
|
641
|
+
{activeTab === 'state' && (<react_native_1.ScrollView style={styles.scrollList} contentContainerStyle={styles.scrollContent}>
|
|
642
|
+
{filteredStateKeys.length === 0 ? (<react_native_1.View style={styles.emptyState}>
|
|
643
|
+
<react_native_1.Text style={styles.emptyStateText}>
|
|
644
|
+
{isSearching ? 'No store slices match your search.' : 'Redux store contains no state.'}
|
|
645
|
+
</react_native_1.Text>
|
|
646
|
+
</react_native_1.View>) : (filteredStateKeys.map(reducerKey => {
|
|
203
647
|
const sliceData = state[reducerKey];
|
|
648
|
+
const fieldsCount = typeof sliceData === 'object' && sliceData !== null
|
|
649
|
+
? Object.keys(sliceData).length
|
|
650
|
+
: 1;
|
|
204
651
|
const lastAction = lastActionMap[reducerKey];
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
652
|
+
const lastUpdatedTime = lastAction ? lastAction.timestamp : 'Initial';
|
|
653
|
+
return (<TouchableScale_1.default key={reducerKey} onPress={() => {
|
|
654
|
+
animateLayout();
|
|
655
|
+
setActiveSliceKey(reducerKey);
|
|
656
|
+
}} style={styles.listRow}>
|
|
657
|
+
<react_native_1.View style={styles.sliceIcon}>
|
|
658
|
+
<NetworkIcons_1.FolderIcon color={AppColors_1.AppColors.purple} size={11}/>
|
|
659
|
+
</react_native_1.View>
|
|
660
|
+
<react_native_1.View style={styles.rowMain}>
|
|
661
|
+
<react_native_1.Text style={styles.rowTitle}>{reducerKey}</react_native_1.Text>
|
|
662
|
+
<react_native_1.Text style={styles.rowSub}>
|
|
663
|
+
{(0, helpers_1.getSize)(sliceData)} • {fieldsCount} {fieldsCount === 1 ? 'field' : 'fields'} • Updated: {lastUpdatedTime}
|
|
664
|
+
</react_native_1.Text>
|
|
665
|
+
</react_native_1.View>
|
|
666
|
+
<ForwardChevronIcon color={AppColors_1.AppColors.grayTextWeak} size={10}/>
|
|
667
|
+
</TouchableScale_1.default>);
|
|
668
|
+
}))}
|
|
669
|
+
</react_native_1.ScrollView>)}
|
|
211
670
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
671
|
+
{/* ── Timeline List View ── */}
|
|
672
|
+
{activeTab === 'timeline' && (<react_native_1.ScrollView style={styles.scrollList} contentContainerStyle={styles.scrollContent}>
|
|
673
|
+
{filteredActionHistory.length === 0 ? (<react_native_1.View style={styles.emptyState}>
|
|
674
|
+
<react_native_1.Text style={styles.emptyStateText}>
|
|
675
|
+
{isSearching
|
|
676
|
+
? 'No actions match your search.'
|
|
677
|
+
: 'No actions dispatched yet. Trigger an action in the app to populate history.'}
|
|
678
|
+
</react_native_1.Text>
|
|
679
|
+
</react_native_1.View>) : (filteredActionHistory.map((action, index) => {
|
|
680
|
+
const id = action.id;
|
|
681
|
+
const affectedSlices = action.affectedSlices || [];
|
|
682
|
+
return (<TouchableScale_1.default key={id} onPress={() => {
|
|
683
|
+
animateLayout();
|
|
684
|
+
setActiveActionId(id);
|
|
685
|
+
}} style={styles.listRow}>
|
|
686
|
+
<react_native_1.View style={styles.seqBadge}>
|
|
687
|
+
<react_native_1.Text style={styles.seqText}>#{action.id}</react_native_1.Text>
|
|
218
688
|
</react_native_1.View>
|
|
219
|
-
<react_native_1.View style={
|
|
220
|
-
<react_native_1.
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
689
|
+
<react_native_1.View style={styles.rowMain}>
|
|
690
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
691
|
+
<NetworkIcons_1.TerminalIcon color={AppColors_1.AppColors.purple} size={11}/>
|
|
692
|
+
<react_native_1.Text style={styles.actionTitleText} numberOfLines={1}>{action.type}</react_native_1.Text>
|
|
693
|
+
</react_native_1.View>
|
|
694
|
+
<react_native_1.View style={styles.actionMetaRow}>
|
|
695
|
+
<NetworkIcons_1.ClockIcon color={AppColors_1.AppColors.grayTextWeak} size={9}/>
|
|
696
|
+
<react_native_1.Text style={styles.actionTimeText}>{action.timestamp} • {(0, helpers_1.getSize)(action.payload)}</react_native_1.Text>
|
|
697
|
+
</react_native_1.View>
|
|
698
|
+
{affectedSlices.length > 0 && (<react_native_1.View style={styles.tagsContainer}>
|
|
699
|
+
{affectedSlices.map(slice => (<react_native_1.View key={slice} style={styles.sliceTagMini}>
|
|
700
|
+
<react_native_1.Text style={styles.sliceTagMiniText}>{slice}</react_native_1.Text>
|
|
701
|
+
</react_native_1.View>))}
|
|
225
702
|
</react_native_1.View>)}
|
|
226
703
|
</react_native_1.View>
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
<react_native_1.View style={styles.childrenVerticalLine}/>
|
|
232
|
-
{typeof sliceData === 'object' && sliceData !== null ? (Object.keys(sliceData).map(k => (<ReduxValueNode key={k} name={k} value={sliceData[k]} level={0} search={search}/>))) : (<ReduxValueNode name={reducerKey} value={sliceData} level={0} search={search} lastAction={lastAction}/>)}
|
|
233
|
-
</react_native_1.View>)}
|
|
234
|
-
</react_native_1.View>);
|
|
235
|
-
})}
|
|
236
|
-
</react_native_1.View>)}
|
|
704
|
+
<ForwardChevronIcon color={AppColors_1.AppColors.grayTextWeak} size={10}/>
|
|
705
|
+
</TouchableScale_1.default>);
|
|
706
|
+
}))}
|
|
707
|
+
</react_native_1.ScrollView>)}
|
|
237
708
|
</react_native_1.View>);
|
|
238
709
|
};
|
|
239
710
|
exports.ReduxTreeView = ReduxTreeView;
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
711
|
+
const styles = react_native_1.StyleSheet.create({
|
|
712
|
+
container: {
|
|
713
|
+
flex: 1,
|
|
714
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
715
|
+
},
|
|
716
|
+
scrollList: {
|
|
717
|
+
flex: 1,
|
|
718
|
+
},
|
|
719
|
+
errorContainer: {
|
|
720
|
+
padding: 24,
|
|
721
|
+
alignItems: 'center',
|
|
722
|
+
},
|
|
723
|
+
errorText: {
|
|
724
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
725
|
+
fontSize: 12,
|
|
726
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
727
|
+
},
|
|
728
|
+
toolbar: {
|
|
729
|
+
flexDirection: 'row',
|
|
730
|
+
alignItems: 'center',
|
|
731
|
+
justifyContent: 'space-between',
|
|
732
|
+
paddingHorizontal: 12,
|
|
733
|
+
paddingVertical: 10,
|
|
734
|
+
backgroundColor: AppColors_1.AppColors.primaryLight,
|
|
735
|
+
borderBottomWidth: 1,
|
|
736
|
+
borderBottomColor: AppColors_1.AppColors.dividerColor,
|
|
243
737
|
},
|
|
244
|
-
|
|
738
|
+
statusSection: {
|
|
245
739
|
flexDirection: 'row',
|
|
246
740
|
alignItems: 'center',
|
|
741
|
+
},
|
|
742
|
+
statusBadge: {
|
|
743
|
+
flexDirection: 'row',
|
|
744
|
+
alignItems: 'center',
|
|
745
|
+
paddingHorizontal: 8,
|
|
247
746
|
paddingVertical: 3,
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
},
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
747
|
+
borderRadius: 12,
|
|
748
|
+
borderWidth: 1,
|
|
749
|
+
},
|
|
750
|
+
statusBadgeActive: {
|
|
751
|
+
backgroundColor: AppColors_1.AppColors.greenStatus,
|
|
752
|
+
borderColor: AppColors_1.AppColors.greenColor + '30',
|
|
753
|
+
},
|
|
754
|
+
statusBadgePaused: {
|
|
755
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
756
|
+
borderColor: AppColors_1.AppColors.grayBorderSecondary,
|
|
757
|
+
},
|
|
758
|
+
statusDot: {
|
|
759
|
+
width: 6,
|
|
760
|
+
height: 6,
|
|
761
|
+
borderRadius: 3,
|
|
762
|
+
marginRight: 6,
|
|
763
|
+
},
|
|
764
|
+
statusDotActive: {
|
|
765
|
+
backgroundColor: AppColors_1.AppColors.greenBaggageText,
|
|
766
|
+
},
|
|
767
|
+
statusDotPaused: {
|
|
768
|
+
backgroundColor: AppColors_1.AppColors.grayTextWeak,
|
|
769
|
+
},
|
|
770
|
+
statusBadgeText: {
|
|
771
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
772
|
+
fontSize: 9,
|
|
773
|
+
letterSpacing: 0.5,
|
|
774
|
+
},
|
|
775
|
+
statusTextActive: {
|
|
776
|
+
color: AppColors_1.AppColors.greenBaggageText,
|
|
777
|
+
},
|
|
778
|
+
statusTextPaused: {
|
|
779
|
+
color: AppColors_1.AppColors.grayText,
|
|
780
|
+
},
|
|
781
|
+
toolbarActions: {
|
|
782
|
+
flexDirection: 'row',
|
|
783
|
+
alignItems: 'center',
|
|
784
|
+
gap: 8,
|
|
785
|
+
},
|
|
786
|
+
iconBtn: {
|
|
787
|
+
width: 28,
|
|
788
|
+
height: 28,
|
|
789
|
+
borderRadius: 6,
|
|
790
|
+
borderWidth: 1,
|
|
791
|
+
borderColor: AppColors_1.AppColors.purple + '40',
|
|
792
|
+
backgroundColor: AppColors_1.AppColors.purpleShade50,
|
|
793
|
+
alignItems: 'center',
|
|
794
|
+
justifyContent: 'center',
|
|
795
|
+
},
|
|
796
|
+
searchContainer: {
|
|
797
|
+
backgroundColor: AppColors_1.AppColors.primaryLight,
|
|
257
798
|
borderBottomWidth: 1,
|
|
258
799
|
borderBottomColor: AppColors_1.AppColors.dividerColor,
|
|
259
|
-
|
|
800
|
+
paddingBottom: 10,
|
|
801
|
+
},
|
|
802
|
+
searchBar: {
|
|
803
|
+
flexDirection: 'row',
|
|
804
|
+
alignItems: 'center',
|
|
805
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
806
|
+
borderRadius: 8,
|
|
807
|
+
marginHorizontal: 12,
|
|
808
|
+
marginTop: 10,
|
|
809
|
+
marginBottom: 8,
|
|
810
|
+
paddingHorizontal: 10,
|
|
811
|
+
borderWidth: 1,
|
|
812
|
+
borderColor: AppColors_1.AppColors.dividerColor,
|
|
813
|
+
height: 36,
|
|
260
814
|
},
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
815
|
+
filterChipRow: {
|
|
816
|
+
flexDirection: 'row',
|
|
817
|
+
alignItems: 'center',
|
|
818
|
+
paddingHorizontal: 12,
|
|
819
|
+
gap: 8,
|
|
820
|
+
},
|
|
821
|
+
filterChipLabel: {
|
|
822
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
823
|
+
fontSize: 9,
|
|
824
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
825
|
+
letterSpacing: 0.5,
|
|
826
|
+
marginRight: 2,
|
|
827
|
+
},
|
|
828
|
+
filterChip: {
|
|
829
|
+
paddingHorizontal: 10,
|
|
830
|
+
paddingVertical: 4,
|
|
831
|
+
borderRadius: 12,
|
|
832
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
833
|
+
borderWidth: 1,
|
|
834
|
+
borderColor: AppColors_1.AppColors.grayBorderSecondary,
|
|
835
|
+
},
|
|
836
|
+
filterChipActive: {
|
|
837
|
+
backgroundColor: AppColors_1.AppColors.purpleShade50,
|
|
838
|
+
borderColor: AppColors_1.AppColors.purple,
|
|
839
|
+
},
|
|
840
|
+
filterChipText: {
|
|
841
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
842
|
+
fontSize: 10,
|
|
843
|
+
color: AppColors_1.AppColors.grayText,
|
|
844
|
+
},
|
|
845
|
+
filterChipTextActive: {
|
|
846
|
+
color: AppColors_1.AppColors.purple,
|
|
847
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
848
|
+
},
|
|
849
|
+
searchInput: {
|
|
850
|
+
flex: 1,
|
|
851
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
852
|
+
fontSize: 12,
|
|
853
|
+
color: AppColors_1.AppColors.grayTextStrong,
|
|
265
854
|
marginLeft: 6,
|
|
855
|
+
padding: 0,
|
|
856
|
+
},
|
|
857
|
+
tabContainer: {
|
|
858
|
+
flexDirection: 'row',
|
|
859
|
+
backgroundColor: AppColors_1.AppColors.dividerColor,
|
|
860
|
+
borderRadius: 8,
|
|
861
|
+
padding: 3,
|
|
862
|
+
marginHorizontal: 12,
|
|
863
|
+
marginTop: 10,
|
|
864
|
+
marginBottom: 10,
|
|
266
865
|
},
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
866
|
+
tabButton: {
|
|
867
|
+
flex: 1,
|
|
868
|
+
paddingVertical: 7,
|
|
270
869
|
alignItems: 'center',
|
|
271
870
|
justifyContent: 'center',
|
|
871
|
+
borderRadius: 6,
|
|
272
872
|
},
|
|
273
|
-
|
|
873
|
+
tabButtonActive: {
|
|
874
|
+
backgroundColor: AppColors_1.AppColors.primaryLight,
|
|
875
|
+
shadowColor: AppColors_1.AppColors.shadowColorString,
|
|
876
|
+
shadowOffset: { width: 0, height: 1 },
|
|
877
|
+
shadowOpacity: 0.08,
|
|
878
|
+
shadowRadius: 2,
|
|
879
|
+
elevation: 2,
|
|
880
|
+
},
|
|
881
|
+
tabButtonText: {
|
|
274
882
|
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
275
|
-
fontSize:
|
|
276
|
-
color: AppColors_1.AppColors.
|
|
883
|
+
fontSize: 12,
|
|
884
|
+
color: AppColors_1.AppColors.grayText,
|
|
277
885
|
},
|
|
278
|
-
|
|
279
|
-
color: AppColors_1.AppColors.
|
|
886
|
+
tabButtonTextActive: {
|
|
887
|
+
color: AppColors_1.AppColors.purple,
|
|
888
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
280
889
|
},
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
890
|
+
scrollContent: {
|
|
891
|
+
paddingBottom: 24,
|
|
892
|
+
paddingHorizontal: 12,
|
|
893
|
+
},
|
|
894
|
+
emptyState: {
|
|
895
|
+
padding: 24,
|
|
896
|
+
alignItems: 'center',
|
|
284
897
|
},
|
|
285
|
-
|
|
898
|
+
emptyStateText: {
|
|
286
899
|
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
287
|
-
fontSize:
|
|
900
|
+
fontSize: 12,
|
|
288
901
|
color: AppColors_1.AppColors.grayTextWeak,
|
|
902
|
+
textAlign: 'center',
|
|
289
903
|
},
|
|
290
|
-
|
|
291
|
-
const styles = react_native_1.StyleSheet.create({
|
|
292
|
-
container: {
|
|
293
|
-
flex: 1,
|
|
294
|
-
},
|
|
295
|
-
storeHeader: {
|
|
904
|
+
listRow: {
|
|
296
905
|
flexDirection: 'row',
|
|
297
906
|
alignItems: 'center',
|
|
298
|
-
backgroundColor: AppColors_1.AppColors.
|
|
299
|
-
borderRadius: 8,
|
|
300
|
-
paddingVertical: 10,
|
|
907
|
+
backgroundColor: AppColors_1.AppColors.primaryLight,
|
|
301
908
|
paddingHorizontal: 12,
|
|
302
|
-
|
|
909
|
+
paddingVertical: 14,
|
|
910
|
+
borderRadius: 10,
|
|
911
|
+
borderWidth: 1,
|
|
912
|
+
borderColor: AppColors_1.AppColors.grayBorderSecondary,
|
|
913
|
+
marginBottom: 8,
|
|
914
|
+
shadowColor: AppColors_1.AppColors.shadowColorString,
|
|
915
|
+
shadowOffset: { width: 0, height: 1 },
|
|
916
|
+
shadowOpacity: 0.03,
|
|
917
|
+
shadowRadius: 2,
|
|
918
|
+
elevation: 1,
|
|
303
919
|
},
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
alignItems: 'center',
|
|
308
|
-
justifyContent: 'center',
|
|
920
|
+
rowMain: {
|
|
921
|
+
flex: 1,
|
|
922
|
+
marginLeft: 10,
|
|
309
923
|
},
|
|
310
|
-
|
|
924
|
+
rowTitle: {
|
|
311
925
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
312
|
-
fontSize:
|
|
313
|
-
color:
|
|
926
|
+
fontSize: 13.5,
|
|
927
|
+
color: AppColors_1.AppColors.primaryBlack,
|
|
314
928
|
},
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
929
|
+
rowSub: {
|
|
930
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
931
|
+
fontSize: 10,
|
|
932
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
933
|
+
marginTop: 2,
|
|
934
|
+
},
|
|
935
|
+
sliceIcon: {
|
|
936
|
+
width: 22,
|
|
937
|
+
height: 22,
|
|
938
|
+
borderRadius: 6,
|
|
939
|
+
backgroundColor: AppColors_1.AppColors.purpleShade50,
|
|
940
|
+
alignItems: 'center',
|
|
941
|
+
justifyContent: 'center',
|
|
942
|
+
},
|
|
943
|
+
seqBadge: {
|
|
944
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
945
|
+
borderColor: AppColors_1.AppColors.grayBorderSecondary,
|
|
946
|
+
borderWidth: 1,
|
|
947
|
+
borderRadius: 4,
|
|
948
|
+
paddingHorizontal: 5,
|
|
318
949
|
paddingVertical: 2,
|
|
319
|
-
|
|
320
|
-
|
|
950
|
+
alignItems: 'center',
|
|
951
|
+
justifyContent: 'center',
|
|
952
|
+
minWidth: 28,
|
|
321
953
|
},
|
|
322
|
-
|
|
954
|
+
seqText: {
|
|
323
955
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
324
|
-
fontSize:
|
|
325
|
-
color:
|
|
956
|
+
fontSize: 9.5,
|
|
957
|
+
color: AppColors_1.AppColors.grayText,
|
|
958
|
+
},
|
|
959
|
+
actionTitleText: {
|
|
960
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
961
|
+
fontSize: 13,
|
|
962
|
+
color: AppColors_1.AppColors.purple,
|
|
963
|
+
},
|
|
964
|
+
actionMetaRow: {
|
|
965
|
+
flexDirection: 'row',
|
|
966
|
+
alignItems: 'center',
|
|
967
|
+
gap: 4,
|
|
968
|
+
marginTop: 2,
|
|
969
|
+
},
|
|
970
|
+
actionTimeText: {
|
|
971
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
972
|
+
fontSize: 9.5,
|
|
973
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
326
974
|
},
|
|
327
|
-
|
|
328
|
-
|
|
975
|
+
tagsContainer: {
|
|
976
|
+
flexDirection: 'row',
|
|
977
|
+
flexWrap: 'wrap',
|
|
978
|
+
gap: 4,
|
|
329
979
|
marginTop: 4,
|
|
330
980
|
},
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
981
|
+
sliceTagMini: {
|
|
982
|
+
backgroundColor: AppColors_1.AppColors.purpleShade50,
|
|
983
|
+
borderColor: AppColors_1.AppColors.purple + '20',
|
|
984
|
+
borderWidth: 1,
|
|
985
|
+
borderRadius: 3,
|
|
986
|
+
paddingHorizontal: 4,
|
|
987
|
+
paddingVertical: 0.5,
|
|
335
988
|
},
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
bottom: 0,
|
|
341
|
-
width: 1,
|
|
342
|
-
backgroundColor: AppColors_1.AppColors.dividerColor,
|
|
989
|
+
sliceTagMiniText: {
|
|
990
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
991
|
+
fontSize: 8.5,
|
|
992
|
+
color: AppColors_1.AppColors.purple,
|
|
343
993
|
},
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
backgroundColor: AppColors_1.AppColors.
|
|
994
|
+
// ── Detail Views Styles ──
|
|
995
|
+
detailHeaderBar: {
|
|
996
|
+
flexDirection: 'row',
|
|
997
|
+
alignItems: 'center',
|
|
998
|
+
paddingHorizontal: 12,
|
|
999
|
+
paddingVertical: 12,
|
|
1000
|
+
backgroundColor: AppColors_1.AppColors.primaryLight,
|
|
1001
|
+
borderBottomWidth: 1,
|
|
1002
|
+
borderBottomColor: AppColors_1.AppColors.dividerColor,
|
|
351
1003
|
},
|
|
352
|
-
|
|
1004
|
+
backBtn: {
|
|
353
1005
|
flexDirection: 'row',
|
|
354
1006
|
alignItems: 'center',
|
|
355
1007
|
paddingVertical: 6,
|
|
1008
|
+
paddingRight: 8,
|
|
1009
|
+
},
|
|
1010
|
+
backBtnText: {
|
|
1011
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1012
|
+
fontSize: 12.5,
|
|
1013
|
+
color: AppColors_1.AppColors.purple,
|
|
1014
|
+
},
|
|
1015
|
+
detailHeaderInfo: {
|
|
1016
|
+
flex: 1,
|
|
1017
|
+
marginLeft: 10,
|
|
1018
|
+
marginRight: 10,
|
|
1019
|
+
},
|
|
1020
|
+
detailTitle: {
|
|
1021
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1022
|
+
fontSize: 13.5,
|
|
1023
|
+
color: AppColors_1.AppColors.primaryBlack,
|
|
1024
|
+
},
|
|
1025
|
+
detailSub: {
|
|
1026
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
1027
|
+
fontSize: 10,
|
|
1028
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
1029
|
+
marginTop: 2,
|
|
1030
|
+
},
|
|
1031
|
+
detailHeaderActions: {
|
|
1032
|
+
flexDirection: 'row',
|
|
1033
|
+
alignItems: 'center',
|
|
356
1034
|
gap: 6,
|
|
357
1035
|
},
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
1036
|
+
detailHeaderBtn: {
|
|
1037
|
+
padding: 6,
|
|
1038
|
+
borderRadius: 6,
|
|
1039
|
+
borderWidth: 1,
|
|
1040
|
+
borderColor: AppColors_1.AppColors.purple + '20',
|
|
362
1041
|
backgroundColor: AppColors_1.AppColors.purpleShade50,
|
|
363
1042
|
alignItems: 'center',
|
|
364
1043
|
justifyContent: 'center',
|
|
1044
|
+
width: 28,
|
|
1045
|
+
height: 28,
|
|
1046
|
+
},
|
|
1047
|
+
detailCopyBtn: {
|
|
1048
|
+
padding: 6,
|
|
1049
|
+
borderRadius: 6,
|
|
1050
|
+
borderWidth: 1,
|
|
1051
|
+
borderColor: AppColors_1.AppColors.purple + '20',
|
|
1052
|
+
backgroundColor: AppColors_1.AppColors.purpleShade50,
|
|
1053
|
+
},
|
|
1054
|
+
detailTimeRow: {
|
|
1055
|
+
flexDirection: 'row',
|
|
1056
|
+
alignItems: 'center',
|
|
1057
|
+
gap: 4,
|
|
1058
|
+
marginTop: 1,
|
|
1059
|
+
},
|
|
1060
|
+
detailTimeText: {
|
|
1061
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
1062
|
+
fontSize: 10,
|
|
1063
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
365
1064
|
},
|
|
366
|
-
|
|
1065
|
+
detailAffectedTags: {
|
|
1066
|
+
paddingHorizontal: 12,
|
|
1067
|
+
paddingVertical: 8,
|
|
1068
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
1069
|
+
borderBottomWidth: 1,
|
|
1070
|
+
borderBottomColor: AppColors_1.AppColors.dividerColor,
|
|
1071
|
+
},
|
|
1072
|
+
affectedTagsLabel: {
|
|
367
1073
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
368
|
-
fontSize:
|
|
369
|
-
color: AppColors_1.AppColors.
|
|
1074
|
+
fontSize: 9,
|
|
1075
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
1076
|
+
letterSpacing: 0.5,
|
|
1077
|
+
marginBottom: 4,
|
|
370
1078
|
},
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
gap: 10,
|
|
376
|
-
},
|
|
377
|
-
childrenVerticalLine: {
|
|
378
|
-
position: 'absolute',
|
|
379
|
-
left: 8,
|
|
380
|
-
top: 0,
|
|
381
|
-
bottom: 16,
|
|
382
|
-
width: 1,
|
|
383
|
-
backgroundColor: AppColors_1.AppColors.dividerColor,
|
|
1079
|
+
detailTagsList: {
|
|
1080
|
+
flexDirection: 'row',
|
|
1081
|
+
flexWrap: 'wrap',
|
|
1082
|
+
gap: 4,
|
|
384
1083
|
},
|
|
385
|
-
|
|
386
|
-
backgroundColor:
|
|
387
|
-
borderColor: '
|
|
1084
|
+
sliceTag: {
|
|
1085
|
+
backgroundColor: AppColors_1.AppColors.purpleShade50,
|
|
1086
|
+
borderColor: AppColors_1.AppColors.purple + '20',
|
|
388
1087
|
borderWidth: 1,
|
|
389
|
-
borderRadius:
|
|
1088
|
+
borderRadius: 4,
|
|
390
1089
|
paddingHorizontal: 6,
|
|
391
|
-
paddingVertical:
|
|
392
|
-
|
|
1090
|
+
paddingVertical: 1.5,
|
|
1091
|
+
},
|
|
1092
|
+
sliceTagText: {
|
|
1093
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
1094
|
+
fontSize: 9.5,
|
|
1095
|
+
color: AppColors_1.AppColors.purple,
|
|
1096
|
+
},
|
|
1097
|
+
subTabRow: {
|
|
1098
|
+
flexDirection: 'row',
|
|
1099
|
+
padding: 8,
|
|
1100
|
+
gap: 8,
|
|
1101
|
+
backgroundColor: AppColors_1.AppColors.primaryLight,
|
|
1102
|
+
borderBottomWidth: 1,
|
|
1103
|
+
borderBottomColor: AppColors_1.AppColors.dividerColor,
|
|
1104
|
+
},
|
|
1105
|
+
subTabPill: {
|
|
1106
|
+
paddingHorizontal: 12,
|
|
1107
|
+
paddingVertical: 5,
|
|
1108
|
+
borderRadius: 12,
|
|
1109
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
1110
|
+
borderWidth: 1,
|
|
1111
|
+
borderColor: AppColors_1.AppColors.grayBorderSecondary,
|
|
1112
|
+
},
|
|
1113
|
+
subTabPillActive: {
|
|
1114
|
+
backgroundColor: AppColors_1.AppColors.purple,
|
|
1115
|
+
borderColor: AppColors_1.AppColors.purple,
|
|
1116
|
+
},
|
|
1117
|
+
subTabPillText: {
|
|
1118
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
1119
|
+
fontSize: 10.5,
|
|
1120
|
+
color: AppColors_1.AppColors.grayText,
|
|
1121
|
+
},
|
|
1122
|
+
subTabPillTextActive: {
|
|
1123
|
+
color: '#FFFFFF',
|
|
1124
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
393
1125
|
},
|
|
394
|
-
|
|
1126
|
+
detailScrollContent: {
|
|
1127
|
+
paddingBottom: 24,
|
|
1128
|
+
},
|
|
1129
|
+
jsonViewerContainer: {
|
|
1130
|
+
paddingHorizontal: 12,
|
|
1131
|
+
paddingVertical: 8,
|
|
1132
|
+
},
|
|
1133
|
+
detailBox: {
|
|
1134
|
+
padding: 10,
|
|
1135
|
+
},
|
|
1136
|
+
detailBoxHeader: {
|
|
1137
|
+
flexDirection: 'row',
|
|
1138
|
+
alignItems: 'center',
|
|
1139
|
+
justifyContent: 'space-between',
|
|
1140
|
+
marginBottom: 8,
|
|
1141
|
+
paddingHorizontal: 4,
|
|
1142
|
+
},
|
|
1143
|
+
detailBoxTitle: {
|
|
395
1144
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
396
1145
|
fontSize: 10,
|
|
397
|
-
color:
|
|
1146
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
1147
|
+
letterSpacing: 0.5,
|
|
1148
|
+
textTransform: 'uppercase',
|
|
1149
|
+
},
|
|
1150
|
+
apiLikeInfoBar: {
|
|
1151
|
+
paddingHorizontal: 16,
|
|
1152
|
+
paddingVertical: 14,
|
|
1153
|
+
backgroundColor: AppColors_1.AppColors.primaryLight,
|
|
1154
|
+
borderBottomWidth: 1,
|
|
1155
|
+
borderBottomColor: AppColors_1.AppColors.dividerColor,
|
|
1156
|
+
},
|
|
1157
|
+
apiBadgeRow: {
|
|
1158
|
+
flexDirection: 'row',
|
|
1159
|
+
alignItems: 'center',
|
|
1160
|
+
gap: 6,
|
|
1161
|
+
marginBottom: 8,
|
|
1162
|
+
},
|
|
1163
|
+
apiMethodBadge: {
|
|
1164
|
+
paddingHorizontal: 8,
|
|
1165
|
+
paddingVertical: 2,
|
|
1166
|
+
borderRadius: 4,
|
|
1167
|
+
alignItems: 'center',
|
|
1168
|
+
justifyContent: 'center',
|
|
1169
|
+
},
|
|
1170
|
+
apiMethodBadgeText: {
|
|
1171
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1172
|
+
fontSize: 9.5,
|
|
1173
|
+
color: '#FFFFFF',
|
|
1174
|
+
letterSpacing: 0.5,
|
|
1175
|
+
},
|
|
1176
|
+
apiChip: {
|
|
1177
|
+
paddingHorizontal: 7,
|
|
1178
|
+
paddingVertical: 2,
|
|
1179
|
+
borderRadius: 4,
|
|
1180
|
+
backgroundColor: 'rgba(104,75,155,0.06)',
|
|
1181
|
+
borderWidth: 1,
|
|
1182
|
+
borderColor: 'rgba(104,75,155,0.15)',
|
|
1183
|
+
alignItems: 'center',
|
|
1184
|
+
justifyContent: 'center',
|
|
1185
|
+
},
|
|
1186
|
+
apiChipText: {
|
|
1187
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1188
|
+
fontSize: 9.5,
|
|
1189
|
+
color: AppColors_1.AppColors.purple,
|
|
1190
|
+
},
|
|
1191
|
+
apiTitleText: {
|
|
1192
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1193
|
+
fontSize: 16,
|
|
1194
|
+
color: AppColors_1.AppColors.primaryBlack,
|
|
1195
|
+
marginBottom: 8,
|
|
1196
|
+
},
|
|
1197
|
+
apiMetaRow: {
|
|
1198
|
+
flexDirection: 'row',
|
|
1199
|
+
alignItems: 'center',
|
|
1200
|
+
gap: 4,
|
|
1201
|
+
},
|
|
1202
|
+
apiMetaText: {
|
|
1203
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
1204
|
+
fontSize: 11,
|
|
1205
|
+
color: AppColors_1.AppColors.grayTextWeak,
|
|
1206
|
+
},
|
|
1207
|
+
contentDetailSubHeader: {
|
|
1208
|
+
flexDirection: 'row',
|
|
1209
|
+
alignItems: 'center',
|
|
1210
|
+
justifyContent: 'space-between',
|
|
1211
|
+
paddingHorizontal: 12,
|
|
1212
|
+
paddingVertical: 10,
|
|
1213
|
+
borderBottomWidth: 1,
|
|
1214
|
+
borderBottomColor: AppColors_1.AppColors.dividerColor,
|
|
1215
|
+
backgroundColor: AppColors_1.AppColors.primaryLight,
|
|
398
1216
|
},
|
|
399
1217
|
});
|