@buoy-gg/storage 2.1.6 → 2.1.9
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/lib/commonjs/storage/components/GameUIStorageBrowser.js +14 -4
- package/lib/commonjs/storage/components/StorageBrowserMode.js +8 -2
- package/lib/commonjs/storage/components/StorageKeyRow.js +78 -80
- package/lib/commonjs/storage/components/StorageKeySection.js +6 -2
- package/lib/commonjs/storage/components/StorageModalWithTabs.js +199 -111
- package/lib/module/storage/components/GameUIStorageBrowser.js +14 -4
- package/lib/module/storage/components/StorageBrowserMode.js +8 -2
- package/lib/module/storage/components/StorageKeyRow.js +79 -81
- package/lib/module/storage/components/StorageKeySection.js +6 -2
- package/lib/module/storage/components/StorageModalWithTabs.js +200 -112
- package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts +4 -1
- package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageBrowserMode.d.ts +4 -1
- package/lib/typescript/storage/components/StorageBrowserMode.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageKeyRow.d.ts +5 -1
- package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageKeySection.d.ts +5 -1
- package/lib/typescript/storage/components/StorageKeySection.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -13,7 +13,6 @@ var _StorageBrowserMode = require("./StorageBrowserMode");
|
|
|
13
13
|
var _clearAllStorage = require("../utils/clearAllStorage");
|
|
14
14
|
var _useStorageEvents = require("../hooks/useStorageEvents");
|
|
15
15
|
var _StorageEventDetailContent = require("./StorageEventDetailContent");
|
|
16
|
-
var _StorageFilterViewV = require("./StorageFilterViewV2");
|
|
17
16
|
var _StorageEventFilterView = require("./StorageEventFilterView");
|
|
18
17
|
var _StorageEventCard = require("./StorageEventCard");
|
|
19
18
|
var _license = require("@buoy-gg/license");
|
|
@@ -36,12 +35,8 @@ function StorageModalWithTabs({
|
|
|
36
35
|
const [activeTab, setActiveTab] = (0, _react.useState)("browser");
|
|
37
36
|
|
|
38
37
|
// Storage Browser state
|
|
39
|
-
const [showStorageFilters, setShowStorageFilters] = (0, _react.useState)(false);
|
|
40
|
-
const [storageIgnoredPatterns, setStorageIgnoredPatterns] = (0, _react.useState)(new Set(["@react_buoy"]) // Auto-hide dev tool keys by default
|
|
41
|
-
);
|
|
42
38
|
const [searchQuery, setSearchQuery] = (0, _react.useState)("");
|
|
43
39
|
const [isSearchActive, setIsSearchActive] = (0, _react.useState)(false);
|
|
44
|
-
const hasLoadedStorageFilters = (0, _react.useRef)(false);
|
|
45
40
|
|
|
46
41
|
// Local state to control subscription (true = subscribed, false = unsubscribed)
|
|
47
42
|
const [isListeningEnabled, setIsListeningEnabled] = (0, _react.useState)(true);
|
|
@@ -57,6 +52,8 @@ function StorageModalWithTabs({
|
|
|
57
52
|
enabled: isListeningEnabled
|
|
58
53
|
});
|
|
59
54
|
const [selectedConversationKey, setSelectedConversationKey] = (0, _react.useState)(null);
|
|
55
|
+
const [selectedHistoryKey, setSelectedHistoryKey] = (0, _react.useState)(null);
|
|
56
|
+
const [selectedHistoryEventIndex, setSelectedHistoryEventIndex] = (0, _react.useState)(null);
|
|
60
57
|
const [selectedEventIndex, setSelectedEventIndex] = (0, _react.useState)(0);
|
|
61
58
|
const [showFilters, setShowFilters] = (0, _react.useState)(false);
|
|
62
59
|
const [ignoredPatterns, setIgnoredPatterns] = (0, _react.useState)(new Set(["@react_buoy", "@RNAsyncStorage", "redux-persist", "persist:"]) // Auto-hide dev tool keys by default
|
|
@@ -189,10 +186,15 @@ function StorageModalWithTabs({
|
|
|
189
186
|
const handleClearEvents = (0, _react.useCallback)(() => {
|
|
190
187
|
clearStorageEvents();
|
|
191
188
|
setSelectedConversationKey(null);
|
|
192
|
-
}, [clearStorageEvents]);
|
|
193
|
-
const handleConversationPress = (0, _react.useCallback)(conversation => {
|
|
194
|
-
setSelectedConversationKey(conversation.key);
|
|
195
189
|
setSelectedEventIndex(0);
|
|
190
|
+
}, [clearStorageEvents]);
|
|
191
|
+
const handleViewHistoryFromBrowser = (0, _react.useCallback)(key => {
|
|
192
|
+
setSelectedHistoryKey(key);
|
|
193
|
+
setSelectedHistoryEventIndex(null);
|
|
194
|
+
}, []);
|
|
195
|
+
const handleBackFromHistory = (0, _react.useCallback)(() => {
|
|
196
|
+
setSelectedHistoryKey(null);
|
|
197
|
+
setSelectedHistoryEventIndex(null);
|
|
196
198
|
}, []);
|
|
197
199
|
const handleTogglePattern = (0, _react.useCallback)(pattern => {
|
|
198
200
|
setIgnoredPatterns(prev => {
|
|
@@ -225,22 +227,26 @@ function StorageModalWithTabs({
|
|
|
225
227
|
|
|
226
228
|
// Storage Browser handlers
|
|
227
229
|
const storageDataRef = (0, _react.useRef)([]);
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
230
|
+
const getStorageSnapshot = (0, _react.useCallback)(() => {
|
|
231
|
+
const keys = storageDataRef.current;
|
|
232
|
+
return {
|
|
233
|
+
timestamp: new Date().toISOString(),
|
|
234
|
+
totalKeys: keys.length,
|
|
235
|
+
asyncStorage: keys.filter(k => k.storageType === 'async').reduce((acc, k) => {
|
|
236
|
+
acc[k.key] = (0, _sharedUi.truncatePayload)(k.value);
|
|
237
|
+
return acc;
|
|
238
|
+
}, {}),
|
|
239
|
+
mmkv: keys.filter(k => k.storageType === 'mmkv').reduce((acc, k) => {
|
|
240
|
+
const id = k.instanceId || 'default';
|
|
241
|
+
if (!acc[id]) acc[id] = {};
|
|
242
|
+
acc[id][k.key] = (0, _sharedUi.truncatePayload)(k.value);
|
|
243
|
+
return acc;
|
|
244
|
+
}, {}),
|
|
245
|
+
secure: keys.filter(k => k.storageType === 'secure').reduce((acc, k) => {
|
|
246
|
+
acc[k.key] = (0, _sharedUi.truncatePayload)(k.value);
|
|
247
|
+
return acc;
|
|
248
|
+
}, {})
|
|
249
|
+
};
|
|
244
250
|
}, []);
|
|
245
251
|
const handlePurgeStorage = (0, _react.useCallback)(async () => {
|
|
246
252
|
_reactNative.Alert.alert("Clear Storage", "Choose what to clear:", [{
|
|
@@ -357,67 +363,154 @@ function StorageModalWithTabs({
|
|
|
357
363
|
return conversations.find(c => c.key === selectedConversationKey) || null;
|
|
358
364
|
}, [selectedConversationKey, conversations]);
|
|
359
365
|
|
|
360
|
-
//
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
+
// Event count per key for storage browser badges
|
|
367
|
+
const eventCountByKey = (0, _react.useMemo)(() => {
|
|
368
|
+
const counts = {};
|
|
369
|
+
conversations.forEach(conv => {
|
|
370
|
+
counts[conv.key] = conv.totalOperations;
|
|
371
|
+
});
|
|
372
|
+
return counts;
|
|
373
|
+
}, [conversations]);
|
|
374
|
+
|
|
375
|
+
// Selected history conversation (from browser tab "view history")
|
|
376
|
+
const selectedHistoryConversation = (0, _react.useMemo)(() => {
|
|
377
|
+
if (!selectedHistoryKey) return null;
|
|
378
|
+
return conversations.find(c => c.key === selectedHistoryKey) || null;
|
|
379
|
+
}, [selectedHistoryKey, conversations]);
|
|
380
|
+
|
|
381
|
+
// Filtered raw events for the events tab (chronological stream, newest-first)
|
|
382
|
+
const filteredEvents = (0, _react.useMemo)(() => {
|
|
383
|
+
return events.filter(event => {
|
|
384
|
+
if (!event.data?.key) return false;
|
|
385
|
+
if (!enabledStorageTypes.has(event.storageType)) return false;
|
|
386
|
+
const key = event.data.key;
|
|
387
|
+
return !Array.from(ignoredPatterns).some(p => key.includes(p));
|
|
388
|
+
});
|
|
389
|
+
}, [events, ignoredPatterns, enabledStorageTypes]);
|
|
390
|
+
const getEventsSnapshot = (0, _react.useCallback)(() => {
|
|
391
|
+
return filteredEvents.map(event => ({
|
|
392
|
+
key: event.data?.key,
|
|
393
|
+
action: event.action,
|
|
394
|
+
value: (0, _sharedUi.truncatePayload)(event.data?.value),
|
|
395
|
+
storageType: event.storageType,
|
|
396
|
+
timestamp: event.timestamp.toISOString()
|
|
397
|
+
}));
|
|
398
|
+
}, [filteredEvents]);
|
|
399
|
+
const visibleEvents = (0, _react.useMemo)(() => {
|
|
400
|
+
if (isPro) return filteredEvents;
|
|
401
|
+
return filteredEvents.slice(0, FREE_TIER_EVENT_LIMIT);
|
|
402
|
+
}, [filteredEvents, isPro]);
|
|
403
|
+
const lockedEventCount = (0, _react.useMemo)(() => {
|
|
366
404
|
if (isPro) return 0;
|
|
367
|
-
return Math.max(0,
|
|
368
|
-
}, [
|
|
405
|
+
return Math.max(0, filteredEvents.length - FREE_TIER_EVENT_LIMIT);
|
|
406
|
+
}, [filteredEvents.length, isPro]);
|
|
369
407
|
|
|
370
408
|
// FlatList optimization constants
|
|
371
409
|
const END_REACHED_THRESHOLD = 0.8;
|
|
372
410
|
|
|
373
|
-
//
|
|
374
|
-
const
|
|
375
|
-
return item.key
|
|
411
|
+
// keyExtractor for raw event FlatList
|
|
412
|
+
const eventKeyExtractor = (0, _react.useCallback)((item, index) => {
|
|
413
|
+
return `${item.timestamp.getTime()}-${item.data?.key || index}`;
|
|
376
414
|
}, []);
|
|
377
415
|
|
|
378
|
-
//
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
416
|
+
// When a raw event card is pressed, open that key's conversation detail at the matching event
|
|
417
|
+
const handleRawEventPress = (0, _react.useCallback)(item => {
|
|
418
|
+
const conv = conversations.find(c => c.key === item.data?.key);
|
|
419
|
+
if (!conv) return;
|
|
420
|
+
const sortedEvents = [...conv.events].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
421
|
+
const eventIndex = sortedEvents.findIndex(e => e.timestamp.getTime() === item.timestamp.getTime());
|
|
422
|
+
setSelectedConversationKey(conv.key);
|
|
423
|
+
setSelectedEventIndex(eventIndex >= 0 ? eventIndex : 0);
|
|
424
|
+
}, [conversations]);
|
|
425
|
+
|
|
426
|
+
// Render a single raw event card
|
|
427
|
+
const renderEventItem = (0, _react.useCallback)(({
|
|
386
428
|
item
|
|
387
429
|
}) => {
|
|
388
430
|
const cardData = {
|
|
389
|
-
key: item.key,
|
|
390
|
-
lastAction: item.
|
|
391
|
-
totalOperations:
|
|
392
|
-
lastEventTimestamp: item.
|
|
393
|
-
storageTypes: item.
|
|
394
|
-
valueType: item.
|
|
431
|
+
key: item.data?.key || "",
|
|
432
|
+
lastAction: item.action,
|
|
433
|
+
totalOperations: 1,
|
|
434
|
+
lastEventTimestamp: item.timestamp,
|
|
435
|
+
storageTypes: new Set([item.storageType]),
|
|
436
|
+
valueType: getValueType(item.data?.value)
|
|
395
437
|
};
|
|
396
438
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageEventCard.StorageEventCard, {
|
|
397
439
|
data: cardData,
|
|
398
|
-
onPress: () =>
|
|
440
|
+
onPress: () => handleRawEventPress(item)
|
|
399
441
|
});
|
|
400
|
-
}, []);
|
|
442
|
+
}, [handleRawEventPress]);
|
|
401
443
|
if (!visible) return null;
|
|
402
444
|
const persistenceKey = enableSharedModalDimensions ? _sharedUi.devToolsStorageKeys.modal.root() : _sharedUi.devToolsStorageKeys.storage.modal();
|
|
403
445
|
const renderContent = () => {
|
|
446
|
+
// Filters overlay — applies to both tabs
|
|
447
|
+
if (showFilters) {
|
|
448
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageEventFilterView.StorageEventFilterView, {
|
|
449
|
+
ignoredPatterns: ignoredPatterns,
|
|
450
|
+
onTogglePattern: handleTogglePattern,
|
|
451
|
+
onAddPattern: handleAddPattern,
|
|
452
|
+
availableKeys: allEventKeys,
|
|
453
|
+
enabledStorageTypes: enabledStorageTypes,
|
|
454
|
+
onToggleStorageType: handleToggleStorageType
|
|
455
|
+
});
|
|
456
|
+
}
|
|
404
457
|
if (activeTab === "browser") {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
458
|
+
// History flow for a specific key (from "view history" in browser tab)
|
|
459
|
+
if (selectedHistoryKey && selectedHistoryConversation) {
|
|
460
|
+
// Level 2: detail view for a specific event
|
|
461
|
+
if (selectedHistoryEventIndex !== null) {
|
|
462
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
463
|
+
style: styles.contentWrapper,
|
|
464
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageEventDetailContent.StorageEventDetailContent, {
|
|
465
|
+
conversation: selectedHistoryConversation,
|
|
466
|
+
selectedEventIndex: selectedHistoryEventIndex,
|
|
467
|
+
onEventIndexChange: setSelectedHistoryEventIndex,
|
|
468
|
+
disableInternalFooter: true
|
|
469
|
+
})
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Level 1: event list for this key (newest-first)
|
|
474
|
+
const ascSortedEvents = [...selectedHistoryConversation.events].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
475
|
+
const newestFirstEvents = [...ascSortedEvents].reverse();
|
|
476
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.FlatList, {
|
|
477
|
+
data: newestFirstEvents,
|
|
478
|
+
keyExtractor: (item, index) => `${item.timestamp.getTime()}-${index}`,
|
|
479
|
+
renderItem: ({
|
|
480
|
+
item
|
|
481
|
+
}) => {
|
|
482
|
+
const ascIdx = ascSortedEvents.findIndex(e => e.timestamp.getTime() === item.timestamp.getTime());
|
|
483
|
+
const cardData = {
|
|
484
|
+
key: item.data?.key || "",
|
|
485
|
+
lastAction: item.action,
|
|
486
|
+
totalOperations: 1,
|
|
487
|
+
lastEventTimestamp: item.timestamp,
|
|
488
|
+
storageTypes: new Set([item.storageType]),
|
|
489
|
+
valueType: getValueType(item.data?.value)
|
|
490
|
+
};
|
|
491
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageEventCard.StorageEventCard, {
|
|
492
|
+
data: cardData,
|
|
493
|
+
onPress: () => setSelectedHistoryEventIndex(ascIdx >= 0 ? ascIdx : 0)
|
|
494
|
+
});
|
|
495
|
+
},
|
|
496
|
+
contentContainerStyle: styles.listContent,
|
|
497
|
+
ItemSeparatorComponent: () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
498
|
+
style: styles.separator
|
|
499
|
+
}),
|
|
500
|
+
initialNumToRender: 20,
|
|
501
|
+
scrollEnabled: false
|
|
411
502
|
});
|
|
412
503
|
}
|
|
413
504
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageBrowserMode.StorageBrowserMode, {
|
|
414
505
|
requiredStorageKeys: requiredStorageKeys,
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
onAddPattern: handleAddStoragePattern,
|
|
506
|
+
ignoredPatterns: ignoredPatterns,
|
|
507
|
+
onTogglePattern: handleTogglePattern,
|
|
508
|
+
onAddPattern: handleAddPattern,
|
|
419
509
|
searchQuery: searchQuery,
|
|
420
|
-
storageDataRef: storageDataRef
|
|
510
|
+
storageDataRef: storageDataRef,
|
|
511
|
+
eventCountByKey: eventCountByKey,
|
|
512
|
+
onViewHistory: handleViewHistoryFromBrowser,
|
|
513
|
+
enabledStorageTypes: enabledStorageTypes
|
|
421
514
|
});
|
|
422
515
|
}
|
|
423
516
|
|
|
@@ -433,17 +526,7 @@ function StorageModalWithTabs({
|
|
|
433
526
|
})
|
|
434
527
|
});
|
|
435
528
|
}
|
|
436
|
-
if (
|
|
437
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageEventFilterView.StorageEventFilterView, {
|
|
438
|
-
ignoredPatterns: ignoredPatterns,
|
|
439
|
-
onTogglePattern: handleTogglePattern,
|
|
440
|
-
onAddPattern: handleAddPattern,
|
|
441
|
-
availableKeys: allEventKeys,
|
|
442
|
-
enabledStorageTypes: enabledStorageTypes,
|
|
443
|
-
onToggleStorageType: handleToggleStorageType
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
if (conversations.length === 0) {
|
|
529
|
+
if (filteredEvents.length === 0) {
|
|
447
530
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
448
531
|
style: styles.emptyState,
|
|
449
532
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Database, {
|
|
@@ -459,18 +542,15 @@ function StorageModalWithTabs({
|
|
|
459
542
|
});
|
|
460
543
|
}
|
|
461
544
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.FlatList, {
|
|
462
|
-
data:
|
|
463
|
-
renderItem:
|
|
464
|
-
keyExtractor:
|
|
545
|
+
data: visibleEvents,
|
|
546
|
+
renderItem: renderEventItem,
|
|
547
|
+
keyExtractor: eventKeyExtractor,
|
|
465
548
|
onEndReachedThreshold: END_REACHED_THRESHOLD,
|
|
466
549
|
contentContainerStyle: styles.listContent,
|
|
467
|
-
|
|
468
|
-
style: styles.separator
|
|
469
|
-
}),
|
|
470
|
-
ListFooterComponent: lockedConversationCount > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
550
|
+
ListFooterComponent: lockedEventCount > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
471
551
|
style: styles.lockedBannerContainer,
|
|
472
552
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ProFeatureBanner, {
|
|
473
|
-
featureName: `${
|
|
553
|
+
featureName: `${lockedEventCount} event${lockedEventCount > 1 ? 's' : ''} locked`,
|
|
474
554
|
description: "Upgrade to Pro to unlock full event history"
|
|
475
555
|
})
|
|
476
556
|
}) : null,
|
|
@@ -484,10 +564,14 @@ function StorageModalWithTabs({
|
|
|
484
564
|
conversation: selectedConversation,
|
|
485
565
|
selectedEventIndex: selectedEventIndex,
|
|
486
566
|
onEventIndexChange: setSelectedEventIndex
|
|
567
|
+
}) : selectedHistoryConversation && selectedHistoryEventIndex !== null ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageEventDetailContent.StorageEventDetailFooter, {
|
|
568
|
+
conversation: selectedHistoryConversation,
|
|
569
|
+
selectedEventIndex: selectedHistoryEventIndex,
|
|
570
|
+
onEventIndexChange: setSelectedHistoryEventIndex
|
|
487
571
|
}) : null;
|
|
488
572
|
|
|
489
573
|
// Determine the appropriate back handler based on current view state
|
|
490
|
-
const currentBackHandler =
|
|
574
|
+
const currentBackHandler = showFilters ? () => setShowFilters(false) : selectedHistoryEventIndex !== null ? () => setSelectedHistoryEventIndex(null) : selectedHistoryKey ? handleBackFromHistory : selectedConversation ? () => {
|
|
491
575
|
setSelectedConversationKey(null);
|
|
492
576
|
setSelectedEventIndex(0);
|
|
493
577
|
} : onBack;
|
|
@@ -499,17 +583,18 @@ function StorageModalWithTabs({
|
|
|
499
583
|
persistenceKey: persistenceKey,
|
|
500
584
|
header: {
|
|
501
585
|
showToggleButton: true,
|
|
502
|
-
customContent:
|
|
586
|
+
customContent: showFilters ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.ModalHeader, {
|
|
503
587
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation, {
|
|
504
|
-
onBack: () =>
|
|
588
|
+
onBack: () => setShowFilters(false)
|
|
505
589
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Content, {
|
|
506
590
|
title: "Filters"
|
|
507
591
|
})]
|
|
508
|
-
}) :
|
|
592
|
+
}) : selectedHistoryKey ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.ModalHeader, {
|
|
509
593
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation, {
|
|
510
|
-
onBack: () =>
|
|
594
|
+
onBack: selectedHistoryEventIndex !== null ? () => setSelectedHistoryEventIndex(null) : handleBackFromHistory
|
|
511
595
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Content, {
|
|
512
|
-
title:
|
|
596
|
+
title: `${selectedHistoryKey} History`,
|
|
597
|
+
centered: true
|
|
513
598
|
})]
|
|
514
599
|
}) : selectedConversation ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.ModalHeader, {
|
|
515
600
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation, {
|
|
@@ -544,13 +629,26 @@ function StorageModalWithTabs({
|
|
|
544
629
|
label: "Storage"
|
|
545
630
|
}, {
|
|
546
631
|
key: "events",
|
|
547
|
-
label: `Events${
|
|
632
|
+
label: `Events${filteredEvents.length > 0 ? ` (${filteredEvents.length})` : ""}`
|
|
548
633
|
}],
|
|
549
634
|
activeTab: activeTab,
|
|
550
|
-
onTabChange: tab =>
|
|
635
|
+
onTabChange: tab => {
|
|
636
|
+
setActiveTab(tab);
|
|
637
|
+
setSelectedHistoryKey(null);
|
|
638
|
+
setSelectedHistoryEventIndex(null);
|
|
639
|
+
setSelectedConversationKey(null);
|
|
640
|
+
setSelectedEventIndex(0);
|
|
641
|
+
}
|
|
551
642
|
})
|
|
552
643
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.ModalHeader.Actions, {
|
|
553
|
-
children: [
|
|
644
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
645
|
+
onPress: handleToggleFilters,
|
|
646
|
+
style: [styles.iconButton, (ignoredPatterns.size > 0 || enabledStorageTypes.size < 3) && styles.activeFilterButton],
|
|
647
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Filter, {
|
|
648
|
+
size: 14,
|
|
649
|
+
color: ignoredPatterns.size > 0 || enabledStorageTypes.size < 3 ? _sharedUi.macOSColors.semantic.debug : _sharedUi.macOSColors.text.secondary
|
|
650
|
+
})
|
|
651
|
+
}), activeTab === "browser" && !isSearchActive && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
554
652
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
555
653
|
onPress: () => setIsSearchActive(true),
|
|
556
654
|
style: styles.iconButton,
|
|
@@ -558,33 +656,23 @@ function StorageModalWithTabs({
|
|
|
558
656
|
size: 14,
|
|
559
657
|
color: _sharedUi.macOSColors.text.secondary
|
|
560
658
|
})
|
|
561
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
size: 14,
|
|
566
|
-
color: storageIgnoredPatterns.size > 0 ? _sharedUi.macOSColors.semantic.debug : _sharedUi.macOSColors.text.secondary
|
|
567
|
-
})
|
|
659
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolbarCopyButton, {
|
|
660
|
+
value: getStorageSnapshot,
|
|
661
|
+
disabled: storageDataRef.current.length === 0,
|
|
662
|
+
buttonStyle: styles.iconButton
|
|
568
663
|
})]
|
|
569
664
|
}), activeTab === "events" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
570
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
size: 14,
|
|
575
|
-
color: ignoredPatterns.size > 0 ? _sharedUi.macOSColors.semantic.debug : _sharedUi.macOSColors.text.secondary
|
|
576
|
-
})
|
|
665
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolbarCopyButton, {
|
|
666
|
+
value: getEventsSnapshot,
|
|
667
|
+
disabled: filteredEvents.length === 0,
|
|
668
|
+
buttonStyle: styles.iconButton
|
|
577
669
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.PowerToggleButton, {
|
|
578
670
|
isEnabled: isListening,
|
|
579
671
|
onToggle: handleToggleListening,
|
|
580
672
|
accessibilityLabel: "Toggle storage event monitoring"
|
|
581
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
673
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolbarClearButton, {
|
|
582
674
|
onPress: handleClearEvents,
|
|
583
|
-
|
|
584
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Trash2, {
|
|
585
|
-
size: 14,
|
|
586
|
-
color: _sharedUi.macOSColors.semantic.error
|
|
587
|
-
})
|
|
675
|
+
buttonStyle: styles.iconButton
|
|
588
676
|
})]
|
|
589
677
|
})]
|
|
590
678
|
})]
|
|
@@ -621,7 +709,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
621
709
|
height: 8
|
|
622
710
|
},
|
|
623
711
|
listContent: {
|
|
624
|
-
paddingVertical:
|
|
712
|
+
paddingVertical: 6
|
|
625
713
|
},
|
|
626
714
|
lockedBannerContainer: {
|
|
627
715
|
marginTop: 8,
|
|
@@ -58,7 +58,10 @@ export function GameUIStorageBrowser({
|
|
|
58
58
|
onTogglePattern,
|
|
59
59
|
onAddPattern,
|
|
60
60
|
searchQuery = "",
|
|
61
|
-
storageDataRef
|
|
61
|
+
storageDataRef,
|
|
62
|
+
eventCountByKey,
|
|
63
|
+
onViewHistory,
|
|
64
|
+
enabledStorageTypes
|
|
62
65
|
}) {
|
|
63
66
|
const isPro = useIsPro();
|
|
64
67
|
const [showUpgradeModal, setShowUpgradeModal] = useState(false);
|
|
@@ -350,7 +353,12 @@ export function GameUIStorageBrowser({
|
|
|
350
353
|
const filteredKeys = useMemo(() => {
|
|
351
354
|
let keys = sortedKeys;
|
|
352
355
|
|
|
353
|
-
// Apply
|
|
356
|
+
// Apply enabled storage types filter (from parent unified filter)
|
|
357
|
+
if (enabledStorageTypes && enabledStorageTypes.size > 0) {
|
|
358
|
+
keys = keys.filter(k => enabledStorageTypes.has(k.storageType));
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Apply ignored pattern filter
|
|
354
362
|
keys = keys.filter(k => {
|
|
355
363
|
// Check if key matches any ignored pattern
|
|
356
364
|
const shouldIgnore = Array.from(ignoredPatterns).some(pattern => k.key.includes(pattern));
|
|
@@ -386,7 +394,7 @@ export function GameUIStorageBrowser({
|
|
|
386
394
|
// No need to filter again here
|
|
387
395
|
|
|
388
396
|
return keys;
|
|
389
|
-
}, [sortedKeys, activeFilter, activeStorageType, ignoredPatterns, searchQuery, selectedMMKVInstance]);
|
|
397
|
+
}, [sortedKeys, activeFilter, activeStorageType, ignoredPatterns, searchQuery, selectedMMKVInstance, enabledStorageTypes]);
|
|
390
398
|
|
|
391
399
|
// For free users, limit visible keys to FREE_TIER_KEY_LIMIT
|
|
392
400
|
const visibleKeys = useMemo(() => {
|
|
@@ -618,7 +626,9 @@ export function GameUIStorageBrowser({
|
|
|
618
626
|
emptyMessage: "",
|
|
619
627
|
isSelectMode: isSelectMode,
|
|
620
628
|
selectedKeys: selectedKeyIds,
|
|
621
|
-
onSelectionChange: handleSelectionChange
|
|
629
|
+
onSelectionChange: handleSelectionChange,
|
|
630
|
+
eventCountByKey: eventCountByKey,
|
|
631
|
+
onViewHistory: onViewHistory
|
|
622
632
|
}), hasLockedKeys && /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
623
633
|
style: styles.limitBanner,
|
|
624
634
|
onPress: () => setShowUpgradeModal(true),
|
|
@@ -13,7 +13,10 @@ export function StorageBrowserMode({
|
|
|
13
13
|
onTogglePattern,
|
|
14
14
|
onAddPattern,
|
|
15
15
|
searchQuery = "",
|
|
16
|
-
storageDataRef
|
|
16
|
+
storageDataRef,
|
|
17
|
+
eventCountByKey,
|
|
18
|
+
onViewHistory,
|
|
19
|
+
enabledStorageTypes
|
|
17
20
|
}) {
|
|
18
21
|
return /*#__PURE__*/_jsx(GameUIStorageBrowser, {
|
|
19
22
|
requiredStorageKeys: requiredStorageKeys,
|
|
@@ -22,6 +25,9 @@ export function StorageBrowserMode({
|
|
|
22
25
|
onTogglePattern: onTogglePattern,
|
|
23
26
|
onAddPattern: onAddPattern,
|
|
24
27
|
searchQuery: searchQuery,
|
|
25
|
-
storageDataRef: storageDataRef
|
|
28
|
+
storageDataRef: storageDataRef,
|
|
29
|
+
eventCountByKey: eventCountByKey,
|
|
30
|
+
onViewHistory: onViewHistory,
|
|
31
|
+
enabledStorageTypes: enabledStorageTypes
|
|
26
32
|
});
|
|
27
33
|
}
|