@buoy-gg/storage 7.0.4 → 7.0.5
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/index.js +77 -1
- package/lib/commonjs/storage/components/DiffViewer/TreeDiffViewer.js +10 -3
- package/lib/commonjs/storage/components/DiffViewer/modes/ThemedSplitView.js +26 -8
- package/lib/commonjs/storage/components/GameUIStorageBrowser.js +263 -115
- package/lib/commonjs/storage/components/GameUIStorageStats.js +7 -7
- package/lib/commonjs/storage/components/MMKVInstanceInfoPanel.js +1 -1
- package/lib/commonjs/storage/components/MMKVInstanceSelector.js +1 -1
- package/lib/commonjs/storage/components/SelectionActionBar.js +2 -36
- package/lib/commonjs/storage/components/StorageActions.js +6 -6
- package/lib/commonjs/storage/components/StorageBrowserMode.js +16 -2
- package/lib/commonjs/storage/components/StorageEventDetailContent.js +106 -149
- package/lib/commonjs/storage/components/StorageEventListener.js +13 -13
- package/lib/commonjs/storage/components/StorageFilterCards.js +13 -135
- package/lib/commonjs/storage/components/StorageKeyCard.js +1 -1
- package/lib/commonjs/storage/components/StorageKeyEditorScreen.js +392 -0
- package/lib/commonjs/storage/components/StorageKeyRow.js +53 -15
- package/lib/commonjs/storage/components/StorageKeySection.js +10 -4
- package/lib/commonjs/storage/components/StorageKeyStats.js +10 -10
- package/lib/commonjs/storage/components/StorageModalWithTabs.js +272 -129
- package/lib/commonjs/storage/components/StorageScalarKeyEditor.js +46 -0
- package/lib/commonjs/storage/components/StorageTypeFilterBar.js +141 -0
- package/lib/commonjs/storage/components/StorageValueEditModal.js +361 -0
- package/lib/commonjs/storage/hooks/useKeyEditor.js +104 -0
- package/lib/commonjs/storage/hooks/useMeasuredWidth.js +74 -0
- package/lib/commonjs/storage/hooks/useSecureStoreKeys.js +70 -15
- package/lib/commonjs/storage/hooks/useTreeDraft.js +107 -0
- package/lib/commonjs/storage/index.js +29 -0
- package/lib/commonjs/storage/stores/storageEventStore.js +4 -2
- package/lib/commonjs/storage/sync/storageSyncAdapter.js +125 -3
- package/lib/commonjs/storage/utils/AsyncStorageListener.js +76 -12
- package/lib/commonjs/storage/utils/MMKVInstanceRegistry.js +10 -9
- package/lib/commonjs/storage/utils/MMKVListener.js +40 -4
- package/lib/commonjs/storage/utils/SecureStoreRegistry.js +52 -1
- package/lib/commonjs/storage/utils/deleteStorageKeys.js +53 -0
- package/lib/commonjs/storage/utils/index.js +13 -0
- package/lib/commonjs/storage/utils/lineDiff.js +21 -354
- package/lib/commonjs/storage/utils/setStorageValue.js +218 -0
- package/lib/commonjs/storage/utils/storageBrowserRefresh.js +49 -0
- package/lib/commonjs/storage/utils/storageOps.js +53 -0
- package/lib/commonjs/storage/utils/storageTimeTravelUtils.js +60 -38
- package/lib/commonjs/storage/utils/valueType.js +24 -0
- package/lib/module/index.js +18 -1
- package/lib/module/storage/components/DiffViewer/TreeDiffViewer.js +10 -3
- package/lib/module/storage/components/DiffViewer/modes/ThemedSplitView.js +26 -8
- package/lib/module/storage/components/GameUIStorageBrowser.js +266 -118
- package/lib/module/storage/components/GameUIStorageStats.js +7 -7
- package/lib/module/storage/components/MMKVInstanceInfoPanel.js +1 -1
- package/lib/module/storage/components/MMKVInstanceSelector.js +1 -1
- package/lib/module/storage/components/SelectionActionBar.js +2 -36
- package/lib/module/storage/components/StorageActions.js +7 -7
- package/lib/module/storage/components/StorageBrowserMode.js +16 -2
- package/lib/module/storage/components/StorageEventDetailContent.js +110 -151
- package/lib/module/storage/components/StorageEventListener.js +14 -14
- package/lib/module/storage/components/StorageFilterCards.js +13 -135
- package/lib/module/storage/components/StorageKeyCard.js +1 -1
- package/lib/module/storage/components/StorageKeyEditorScreen.js +388 -0
- package/lib/module/storage/components/StorageKeyRow.js +55 -17
- package/lib/module/storage/components/StorageKeySection.js +11 -5
- package/lib/module/storage/components/StorageKeyStats.js +11 -10
- package/lib/module/storage/components/StorageModalWithTabs.js +272 -130
- package/lib/module/storage/components/StorageScalarKeyEditor.js +42 -0
- package/lib/module/storage/components/StorageTypeFilterBar.js +136 -0
- package/lib/module/storage/components/StorageValueEditModal.js +357 -0
- package/lib/module/storage/hooks/useKeyEditor.js +100 -0
- package/lib/module/storage/hooks/useMeasuredWidth.js +71 -0
- package/lib/module/storage/hooks/useSecureStoreKeys.js +71 -16
- package/lib/module/storage/hooks/useTreeDraft.js +103 -0
- package/lib/module/storage/index.js +3 -0
- package/lib/module/storage/stores/storageEventStore.js +4 -2
- package/lib/module/storage/sync/storageSyncAdapter.js +125 -3
- package/lib/module/storage/utils/AsyncStorageListener.js +76 -12
- package/lib/module/storage/utils/MMKVInstanceRegistry.js +8 -7
- package/lib/module/storage/utils/MMKVListener.js +40 -4
- package/lib/module/storage/utils/SecureStoreRegistry.js +52 -1
- package/lib/module/storage/utils/deleteStorageKeys.js +49 -0
- package/lib/module/storage/utils/index.js +3 -0
- package/lib/module/storage/utils/lineDiff.js +7 -354
- package/lib/module/storage/utils/setStorageValue.js +209 -0
- package/lib/module/storage/utils/storageBrowserRefresh.js +44 -0
- package/lib/module/storage/utils/storageOps.js +46 -0
- package/lib/module/storage/utils/storageTimeTravelUtils.js +61 -40
- package/lib/module/storage/utils/valueType.js +23 -0
- package/lib/typescript/index.d.ts +12 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts +4 -1
- package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts.map +1 -1
- package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts +7 -1
- package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts.map +1 -1
- package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts +27 -1
- package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +1 -1
- package/lib/typescript/storage/components/SelectionActionBar.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageBrowserMode.d.ts +17 -1
- package/lib/typescript/storage/components/StorageBrowserMode.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageEventDetailContent.d.ts +4 -1
- package/lib/typescript/storage/components/StorageEventDetailContent.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageFilterCards.d.ts +9 -3
- package/lib/typescript/storage/components/StorageFilterCards.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageKeyEditorScreen.d.ts +42 -0
- package/lib/typescript/storage/components/StorageKeyEditorScreen.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageKeyRow.d.ts +17 -0
- package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageKeySection.d.ts +7 -1
- package/lib/typescript/storage/components/StorageKeySection.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageKeyStats.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts +28 -1
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageScalarKeyEditor.d.ts +24 -0
- package/lib/typescript/storage/components/StorageScalarKeyEditor.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts +29 -0
- package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageValueEditModal.d.ts +36 -0
- package/lib/typescript/storage/components/StorageValueEditModal.d.ts.map +1 -0
- package/lib/typescript/storage/hooks/useKeyEditor.d.ts +51 -0
- package/lib/typescript/storage/hooks/useKeyEditor.d.ts.map +1 -0
- package/lib/typescript/storage/hooks/useMeasuredWidth.d.ts +37 -0
- package/lib/typescript/storage/hooks/useMeasuredWidth.d.ts.map +1 -0
- package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts +8 -1
- package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts.map +1 -1
- package/lib/typescript/storage/hooks/useTreeDraft.d.ts +67 -0
- package/lib/typescript/storage/hooks/useTreeDraft.d.ts.map +1 -0
- package/lib/typescript/storage/index.d.ts +2 -0
- package/lib/typescript/storage/index.d.ts.map +1 -1
- package/lib/typescript/storage/sync/storageSyncAdapter.d.ts +41 -0
- package/lib/typescript/storage/sync/storageSyncAdapter.d.ts.map +1 -1
- package/lib/typescript/storage/utils/AsyncStorageListener.d.ts +15 -0
- package/lib/typescript/storage/utils/AsyncStorageListener.d.ts.map +1 -1
- package/lib/typescript/storage/utils/MMKVInstanceRegistry.d.ts.map +1 -1
- package/lib/typescript/storage/utils/MMKVListener.d.ts +7 -0
- package/lib/typescript/storage/utils/MMKVListener.d.ts.map +1 -1
- package/lib/typescript/storage/utils/SecureStoreRegistry.d.ts +20 -0
- package/lib/typescript/storage/utils/SecureStoreRegistry.d.ts.map +1 -1
- package/lib/typescript/storage/utils/deleteStorageKeys.d.ts +27 -0
- package/lib/typescript/storage/utils/deleteStorageKeys.d.ts.map +1 -0
- package/lib/typescript/storage/utils/index.d.ts +1 -0
- package/lib/typescript/storage/utils/index.d.ts.map +1 -1
- package/lib/typescript/storage/utils/lineDiff.d.ts +7 -31
- package/lib/typescript/storage/utils/lineDiff.d.ts.map +1 -1
- package/lib/typescript/storage/utils/setStorageValue.d.ts +64 -0
- package/lib/typescript/storage/utils/setStorageValue.d.ts.map +1 -0
- package/lib/typescript/storage/utils/storageBrowserRefresh.d.ts +28 -0
- package/lib/typescript/storage/utils/storageBrowserRefresh.d.ts.map +1 -0
- package/lib/typescript/storage/utils/storageOps.d.ts +25 -0
- package/lib/typescript/storage/utils/storageOps.d.ts.map +1 -0
- package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts +15 -5
- package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts.map +1 -1
- package/lib/typescript/storage/utils/valueType.d.ts +13 -0
- package/lib/typescript/storage/utils/valueType.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -9,6 +9,7 @@ var _react = require("react");
|
|
|
9
9
|
var _reactNative = require("react-native");
|
|
10
10
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
11
11
|
var _StorageKeySection = require("./StorageKeySection");
|
|
12
|
+
var _StorageKeyEditorScreen = require("./StorageKeyEditorScreen");
|
|
12
13
|
var _StorageFilterCards = require("./StorageFilterCards");
|
|
13
14
|
var _useAsyncStorageKeys = require("../hooks/useAsyncStorageKeys");
|
|
14
15
|
var _AsyncStorageListener = require("../utils/AsyncStorageListener");
|
|
@@ -18,6 +19,8 @@ var _useMMKVInstances = require("../hooks/useMMKVInstances");
|
|
|
18
19
|
var _StorageActionButtons = require("./StorageActionButtons");
|
|
19
20
|
var _SelectionActionBar = require("./SelectionActionBar");
|
|
20
21
|
var _MMKVListener = require("../utils/MMKVListener");
|
|
22
|
+
var _storageBrowserRefresh = require("../utils/storageBrowserRefresh");
|
|
23
|
+
var _setStorageValue = require("../utils/setStorageValue");
|
|
21
24
|
var _license = require("@buoy-gg/license");
|
|
22
25
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
23
26
|
// Pure JS (no react-native-mmkv dependency) — works with any registered
|
|
@@ -59,10 +62,17 @@ function GameUIStorageBrowser({
|
|
|
59
62
|
searchQuery = "",
|
|
60
63
|
storageDataRef,
|
|
61
64
|
eventCountByKey,
|
|
65
|
+
lastWriteByKey,
|
|
62
66
|
onViewHistory,
|
|
63
67
|
enabledStorageTypes,
|
|
68
|
+
statusFilter,
|
|
69
|
+
onStatusFilterChange,
|
|
70
|
+
onStatusCountsChange,
|
|
64
71
|
pinnedKeys,
|
|
65
|
-
onTogglePin
|
|
72
|
+
onTogglePin,
|
|
73
|
+
storageTypeFilter,
|
|
74
|
+
onStorageTypeFilterChange,
|
|
75
|
+
applySafeAreaInset
|
|
66
76
|
}) {
|
|
67
77
|
const isPro = (0, _license.useIsPro)();
|
|
68
78
|
const [showUpgradeModal, setShowUpgradeModal] = (0, _react.useState)(false);
|
|
@@ -73,10 +83,29 @@ function GameUIStorageBrowser({
|
|
|
73
83
|
setShowUpgradeModal(false);
|
|
74
84
|
}
|
|
75
85
|
}, [showUpgradeModal, isPro]);
|
|
76
|
-
const [
|
|
77
|
-
|
|
86
|
+
const [internalFilter, setInternalFilter] = (0, _react.useState)("all");
|
|
87
|
+
// Controlled when the host supplies both halves; uncontrolled otherwise.
|
|
88
|
+
const isFilterControlled = statusFilter != null && onStatusFilterChange != null;
|
|
89
|
+
const activeFilter = isFilterControlled ? statusFilter : internalFilter;
|
|
90
|
+
const setActiveFilter = isFilterControlled ? onStatusFilterChange : setInternalFilter;
|
|
91
|
+
const [internalStorageType, setInternalStorageType] = (0, _react.useState)("all");
|
|
92
|
+
// Controlled when the host supplies both halves — the modal does, so the
|
|
93
|
+
// Events tab shows the same backend you picked here.
|
|
94
|
+
const isStorageTypeControlled = storageTypeFilter != null && onStorageTypeFilterChange != null;
|
|
95
|
+
const activeStorageType = isStorageTypeControlled ? storageTypeFilter : internalStorageType;
|
|
96
|
+
const setActiveStorageType = isStorageTypeControlled ? onStorageTypeFilterChange : setInternalStorageType;
|
|
78
97
|
const [selectedMMKVInstance, setSelectedMMKVInstance] = (0, _react.useState)(null);
|
|
79
98
|
|
|
99
|
+
/**
|
|
100
|
+
* The key the full-screen editor is open on, if any.
|
|
101
|
+
*
|
|
102
|
+
* Held here rather than in the row because the editor covers the whole
|
|
103
|
+
* browser, and because the write it eventually performs is `handleSaveValue`
|
|
104
|
+
* — which needs the MMKV instance registry and the refresh fan-out that live
|
|
105
|
+
* at this level.
|
|
106
|
+
*/
|
|
107
|
+
const [editingKey, setEditingKey] = (0, _react.useState)(null);
|
|
108
|
+
|
|
80
109
|
// Selection mode state
|
|
81
110
|
const [isSelectMode, setIsSelectMode] = (0, _react.useState)(false);
|
|
82
111
|
const [selectedKeyIds, setSelectedKeyIds] = (0, _react.useState)(new Set());
|
|
@@ -190,6 +219,40 @@ function GameUIStorageBrowser({
|
|
|
190
219
|
setIsSelectMode(false);
|
|
191
220
|
}, [onAddPattern]);
|
|
192
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Write an edited value back to the device.
|
|
224
|
+
*
|
|
225
|
+
* Pro is checked here rather than on the Edit button because the technical
|
|
226
|
+
* blocks (`storageEditBlockedReason`) and the licence are different kinds of
|
|
227
|
+
* "no": the former means this key can never be edited and the row says so
|
|
228
|
+
* permanently, the latter is an upsell. Throwing lets the editor keep the
|
|
229
|
+
* draft on screen instead of discarding what was typed.
|
|
230
|
+
*/
|
|
231
|
+
const handleSaveValue = (0, _react.useCallback)(async (storageKey, raw) => {
|
|
232
|
+
if (!isPro) {
|
|
233
|
+
setShowUpgradeModal(true);
|
|
234
|
+
throw new Error("Editing storage values is a Pro feature.");
|
|
235
|
+
}
|
|
236
|
+
await (0, _setStorageValue.setStorageValue)(storageKey, raw, mmkvInstances);
|
|
237
|
+
refresh();
|
|
238
|
+
}, [isPro, mmkvInstances, refresh]);
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Flip a boolean key straight from its card.
|
|
242
|
+
*
|
|
243
|
+
* Goes through `handleSaveValue` like every other write, so the Pro gate and
|
|
244
|
+
* the type preservation are the same ones the editor uses — this is only a
|
|
245
|
+
* shortcut past the UI, not past the rules.
|
|
246
|
+
*/
|
|
247
|
+
const handleToggleKey = (0, _react.useCallback)(storageKey => {
|
|
248
|
+
void handleSaveValue(storageKey, JSON.stringify(!storageKey.value)).catch(e => {
|
|
249
|
+
_reactNative.Alert.alert("Couldn't save", e instanceof Error ? e.message : String(e));
|
|
250
|
+
});
|
|
251
|
+
}, [handleSaveValue]);
|
|
252
|
+
|
|
253
|
+
/** Permanent, per-key reasons a value can't be edited (never the licence). */
|
|
254
|
+
const editBlockedFor = (0, _react.useCallback)(storageKey => (0, _setStorageValue.storageEditBlockedReason)(storageKey, mmkvInstances), [mmkvInstances]);
|
|
255
|
+
|
|
193
256
|
// Memoized export data for copy functionality
|
|
194
257
|
const copyExportData = (0, _react.useMemo)(() => {
|
|
195
258
|
const allKeys = allStorageKeys;
|
|
@@ -255,12 +318,34 @@ function GameUIStorageBrowser({
|
|
|
255
318
|
};
|
|
256
319
|
}, [refreshAsync]);
|
|
257
320
|
|
|
321
|
+
// Auto-refresh when something outside this component knows the underlying
|
|
322
|
+
// storage changed. On device the listeners above cover it; in remote-mirror
|
|
323
|
+
// mode (desktop dashboard) local capture is suppressed and they never fire,
|
|
324
|
+
// so the dashboard signals each incoming device snapshot this way — without
|
|
325
|
+
// it the browse tab is frozen at whatever it read on mount.
|
|
326
|
+
(0, _react.useEffect)(() => {
|
|
327
|
+
let timeoutId;
|
|
328
|
+
const unsubscribe = (0, _storageBrowserRefresh.onStorageBrowserRefresh)(() => {
|
|
329
|
+
clearTimeout(timeoutId);
|
|
330
|
+
timeoutId = setTimeout(refresh, 100);
|
|
331
|
+
});
|
|
332
|
+
return () => {
|
|
333
|
+
clearTimeout(timeoutId);
|
|
334
|
+
unsubscribe();
|
|
335
|
+
};
|
|
336
|
+
}, [refresh]);
|
|
337
|
+
|
|
258
338
|
// Auto-refresh on MMKV storage events
|
|
259
339
|
(0, _react.useEffect)(() => {
|
|
260
340
|
let timeoutId;
|
|
261
341
|
const unsubscribe = (0, _MMKVListener.addMMKVListener)(event => {
|
|
262
|
-
//
|
|
263
|
-
|
|
342
|
+
// Refresh when the changed instance is one we're actually showing.
|
|
343
|
+
// `selectedMMKVInstance` is null by default ("All instances"), so
|
|
344
|
+
// comparing it to event.instanceId directly was never true for the view
|
|
345
|
+
// every user starts on — MMKV values sat stale in the browse list until
|
|
346
|
+
// it remounted, even though the write was recorded in Events.
|
|
347
|
+
const affectsView = selectedMMKVInstance === null || event.instanceId === selectedMMKVInstance;
|
|
348
|
+
if (affectsView) {
|
|
264
349
|
clearTimeout(timeoutId);
|
|
265
350
|
timeoutId = setTimeout(() => {
|
|
266
351
|
refreshMMKV(); // Auto-refresh MMKV when it changes
|
|
@@ -345,6 +430,15 @@ function GameUIStorageBrowser({
|
|
|
345
430
|
};
|
|
346
431
|
}, [allStorageKeys, activeFilter, activeStorageType]);
|
|
347
432
|
|
|
433
|
+
// Push the status counts to a host toolbar that renders them (desktop).
|
|
434
|
+
(0, _react.useEffect)(() => {
|
|
435
|
+
onStatusCountsChange?.({
|
|
436
|
+
validCount: tabStats.validCount,
|
|
437
|
+
missingCount: tabStats.missingCount,
|
|
438
|
+
issuesCount: tabStats.issuesCount
|
|
439
|
+
});
|
|
440
|
+
}, [onStatusCountsChange, tabStats.validCount, tabStats.missingCount, tabStats.issuesCount]);
|
|
441
|
+
|
|
348
442
|
// Sort all keys by priority (issues first)
|
|
349
443
|
const sortedKeys = (0, _react.useMemo)(() => {
|
|
350
444
|
// Sort by status priority: errors first, then warnings, then valid
|
|
@@ -466,6 +560,11 @@ function GameUIStorageBrowser({
|
|
|
466
560
|
setSelectedKeyIds(new Set());
|
|
467
561
|
}, []);
|
|
468
562
|
|
|
563
|
+
/**
|
|
564
|
+
* Serialized size of everything in storage, for the table's footer summary.
|
|
565
|
+
* Keyed on `allStorageKeys` rather than the filtered set: it answers "how much
|
|
566
|
+
* is in here", which a filter should not change.
|
|
567
|
+
*/
|
|
469
568
|
// Calculate health percentage
|
|
470
569
|
const healthPercentage = stats.requiredCount > 0 ? Math.round(stats.presentRequiredCount / stats.requiredCount * 100) : stats.totalCount > 0 ? 100 : 0;
|
|
471
570
|
const healthStatus = healthPercentage >= 90 ? "OPTIMAL" : healthPercentage >= 70 ? "WARNING" : "CRITICAL";
|
|
@@ -503,23 +602,15 @@ function GameUIStorageBrowser({
|
|
|
503
602
|
})]
|
|
504
603
|
});
|
|
505
604
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
healthPercentage: healthPercentage,
|
|
516
|
-
healthStatus: healthStatus,
|
|
517
|
-
healthColor: healthColor,
|
|
518
|
-
activeFilter: activeFilter,
|
|
519
|
-
onFilterChange: setActiveFilter,
|
|
520
|
-
activeStorageType: activeStorageType,
|
|
521
|
-
onStorageTypeChange: setActiveStorageType
|
|
522
|
-
}), activeStorageType === "mmkv" && mmkvInstances.length === 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
605
|
+
|
|
606
|
+
/* ---------------------------------------------------------------- *
|
|
607
|
+
* Subtrees the card list composes. Extracted rather than inlined so Pro
|
|
608
|
+
* gating and MMKV
|
|
609
|
+
* instance selection or the empty-state copy.
|
|
610
|
+
* ---------------------------------------------------------------- */
|
|
611
|
+
|
|
612
|
+
const mmkvSection = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
613
|
+
children: [activeStorageType === "mmkv" && mmkvInstances.length === 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
523
614
|
style: styles.emptyMMKVState,
|
|
524
615
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
525
616
|
style: styles.emptyMMKVTitle,
|
|
@@ -603,102 +694,159 @@ function GameUIStorageBrowser({
|
|
|
603
694
|
}, inst.id);
|
|
604
695
|
})]
|
|
605
696
|
})]
|
|
606
|
-
})
|
|
607
|
-
|
|
697
|
+
})]
|
|
698
|
+
});
|
|
699
|
+
const actionButtonsNode = /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageActionButtons.StorageActionButtons, {
|
|
700
|
+
copyValue: copyExportData,
|
|
701
|
+
mmkvInstances: mmkvInstances.map(inst => ({
|
|
702
|
+
id: inst.id,
|
|
703
|
+
instance: inst.instance
|
|
704
|
+
})),
|
|
705
|
+
activeStorageType: activeStorageType,
|
|
706
|
+
onClearComplete: refresh,
|
|
707
|
+
isSelectMode: isSelectMode,
|
|
708
|
+
onToggleSelectMode: handleToggleSelectMode,
|
|
709
|
+
selectedCount: selectedKeyIds.size
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
/* Selection Action Bar - Only show in select mode with selections */
|
|
713
|
+
const selectionBarNode = isSelectMode ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_SelectionActionBar.SelectionActionBar, {
|
|
714
|
+
selectedKeys: selectedKeysInfo,
|
|
715
|
+
mmkvInstances: mmkvInstances.map(inst => ({
|
|
716
|
+
id: inst.id,
|
|
717
|
+
instance: inst.instance
|
|
718
|
+
})),
|
|
719
|
+
onDeleteComplete: handleDeleteComplete,
|
|
720
|
+
onHideKeys: handleHideKeys,
|
|
721
|
+
onSelectAll: handleSelectAll,
|
|
722
|
+
onClearSelection: handleClearSelection,
|
|
723
|
+
totalVisibleKeys: visibleKeys.length
|
|
724
|
+
}) : null;
|
|
725
|
+
const lockedBannerNode = hasLockedKeys ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
726
|
+
style: styles.limitBanner,
|
|
727
|
+
onPress: () => setShowUpgradeModal(true),
|
|
728
|
+
activeOpacity: 0.8,
|
|
729
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
730
|
+
style: styles.limitBannerContent,
|
|
608
731
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
609
|
-
style: styles.
|
|
610
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
style: styles.sectionTitle,
|
|
614
|
-
children: [activeFilter === "all" ? "KEYS" : activeFilter === "missing" ? "MISSING KEYS" : "ISSUES TO FIX", activeStorageType !== "all" && ` (${activeStorageType.toUpperCase()})`]
|
|
615
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
616
|
-
style: styles.countBadge,
|
|
617
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
618
|
-
style: styles.countText,
|
|
619
|
-
children: visibleKeys.length
|
|
620
|
-
})
|
|
621
|
-
})]
|
|
622
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageActionButtons.StorageActionButtons, {
|
|
623
|
-
copyValue: copyExportData,
|
|
624
|
-
mmkvInstances: mmkvInstances.map(inst => ({
|
|
625
|
-
id: inst.id,
|
|
626
|
-
instance: inst.instance
|
|
627
|
-
})),
|
|
628
|
-
activeStorageType: activeStorageType,
|
|
629
|
-
onClearComplete: refresh,
|
|
630
|
-
isSelectMode: isSelectMode,
|
|
631
|
-
onToggleSelectMode: handleToggleSelectMode,
|
|
632
|
-
selectedCount: selectedKeyIds.size
|
|
633
|
-
})]
|
|
634
|
-
}), isSelectMode && /*#__PURE__*/(0, _jsxRuntime.jsx)(_SelectionActionBar.SelectionActionBar, {
|
|
635
|
-
selectedKeys: selectedKeysInfo,
|
|
636
|
-
mmkvInstances: mmkvInstances.map(inst => ({
|
|
637
|
-
id: inst.id,
|
|
638
|
-
instance: inst.instance
|
|
639
|
-
})),
|
|
640
|
-
onDeleteComplete: handleDeleteComplete,
|
|
641
|
-
onHideKeys: handleHideKeys,
|
|
642
|
-
onSelectAll: handleSelectAll,
|
|
643
|
-
onClearSelection: handleClearSelection,
|
|
644
|
-
totalVisibleKeys: visibleKeys.length
|
|
645
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageKeySection.StorageKeySection, {
|
|
646
|
-
title: "",
|
|
647
|
-
count: -1,
|
|
648
|
-
keys: visibleKeys,
|
|
649
|
-
emptyMessage: "",
|
|
650
|
-
isSelectMode: isSelectMode,
|
|
651
|
-
selectedKeys: selectedKeyIds,
|
|
652
|
-
onSelectionChange: handleSelectionChange,
|
|
653
|
-
eventCountByKey: eventCountByKey,
|
|
654
|
-
onViewHistory: onViewHistory,
|
|
655
|
-
onHideKey: key => handleHideKeys([key]),
|
|
656
|
-
pinnedKeys: pinnedKeys,
|
|
657
|
-
onTogglePin: onTogglePin
|
|
658
|
-
}), hasLockedKeys && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
659
|
-
style: styles.limitBanner,
|
|
660
|
-
onPress: () => setShowUpgradeModal(true),
|
|
661
|
-
activeOpacity: 0.8,
|
|
662
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
663
|
-
style: styles.limitBannerContent,
|
|
664
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
665
|
-
style: styles.limitBannerLeft,
|
|
666
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Zap, {
|
|
667
|
-
size: 16,
|
|
668
|
-
color: "#20C997"
|
|
669
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
670
|
-
style: styles.limitBannerText,
|
|
671
|
-
children: searchQuery ? `${lockedKeyCount} matching ${lockedKeyCount === 1 ? 'key' : 'keys'} in locked storage` : `${lockedKeyCount} keys locked`
|
|
672
|
-
})]
|
|
673
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ProBadge, {})]
|
|
732
|
+
style: styles.limitBannerLeft,
|
|
733
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Zap, {
|
|
734
|
+
size: 16,
|
|
735
|
+
color: _sharedUi.buoyColors.primary
|
|
674
736
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
675
|
-
style: styles.
|
|
676
|
-
children: searchQuery ?
|
|
737
|
+
style: styles.limitBannerText,
|
|
738
|
+
children: searchQuery ? `${lockedKeyCount} matching ${lockedKeyCount === 1 ? 'key' : 'keys'} in locked storage` : `${lockedKeyCount} keys locked`
|
|
677
739
|
})]
|
|
678
|
-
})]
|
|
679
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
680
|
-
style: styles.emptyState,
|
|
681
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Database, {
|
|
682
|
-
size: 32,
|
|
683
|
-
color: _sharedUi.macOSColors.text.muted
|
|
684
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
685
|
-
style: styles.emptyTitle,
|
|
686
|
-
children: searchQuery ? "No results found" : activeFilter === "all" ? "No valid keys found" : activeFilter === "missing" ? "No missing keys" : "No issues found"
|
|
687
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
688
|
-
style: styles.emptySubtitle,
|
|
689
|
-
children: searchQuery ? `No keys matching "${searchQuery}"` : activeFilter === "all" ? "All keys have issues or are missing" : activeFilter === "missing" ? "All required keys are present" : "All storage keys are correctly configured"
|
|
690
|
-
})]
|
|
740
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ProBadge, {})]
|
|
691
741
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
692
|
-
style: styles.
|
|
693
|
-
children: "
|
|
694
|
-
})
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
742
|
+
style: styles.limitBannerSubtext,
|
|
743
|
+
children: searchQuery ? "Upgrade to Pro to search your full storage" : "Upgrade to Pro to unlock full storage access"
|
|
744
|
+
})]
|
|
745
|
+
}) : null;
|
|
746
|
+
const emptyStateNode = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
747
|
+
style: styles.emptyState,
|
|
748
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Database, {
|
|
749
|
+
size: 32,
|
|
750
|
+
color: _sharedUi.macOSColors.text.muted
|
|
751
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
752
|
+
style: styles.emptyTitle,
|
|
753
|
+
children: searchQuery ? "No results found" : activeFilter === "all" ? "No valid keys found" : activeFilter === "missing" ? "No missing keys" : "No issues found"
|
|
754
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
755
|
+
style: styles.emptySubtitle,
|
|
756
|
+
children: searchQuery ? `No keys matching "${searchQuery}"` : activeFilter === "all" ? "All keys have issues or are missing" : activeFilter === "missing" ? "All required keys are present" : "All storage keys are correctly configured"
|
|
698
757
|
})]
|
|
699
758
|
});
|
|
759
|
+
const upgradeModalNode = /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ProUpgradeModal, {
|
|
760
|
+
visible: showUpgradeModal,
|
|
761
|
+
onClose: () => setShowUpgradeModal(false),
|
|
762
|
+
featureName: "Storage Keys"
|
|
763
|
+
});
|
|
764
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
765
|
+
style: styles.root,
|
|
766
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
|
|
767
|
+
style: styles.scrollContainer,
|
|
768
|
+
contentContainerStyle: styles.container,
|
|
769
|
+
showsVerticalScrollIndicator: false,
|
|
770
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
771
|
+
style: styles.backgroundGrid
|
|
772
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageFilterCards.StorageFilterCards, {
|
|
773
|
+
stats: stats,
|
|
774
|
+
tabStats: tabStats,
|
|
775
|
+
healthPercentage: healthPercentage,
|
|
776
|
+
healthStatus: healthStatus,
|
|
777
|
+
healthColor: healthColor,
|
|
778
|
+
activeFilter: activeFilter,
|
|
779
|
+
onFilterChange: setActiveFilter,
|
|
780
|
+
activeStorageType: activeStorageType,
|
|
781
|
+
onStorageTypeChange: setActiveStorageType
|
|
782
|
+
// Same rule the wide bar follows: when a host toolbar owns the status
|
|
783
|
+
// filter it also renders the counters, so ours would be a second copy.
|
|
784
|
+
,
|
|
785
|
+
showStatus: !isFilterControlled
|
|
786
|
+
}), mmkvSection, filteredKeys.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
787
|
+
style: styles.keysSection,
|
|
788
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
789
|
+
style: styles.sectionHeader,
|
|
790
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
791
|
+
style: styles.sectionHeaderLeft,
|
|
792
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
793
|
+
style: styles.sectionTitle,
|
|
794
|
+
children: [activeFilter === "all" ? "KEYS" : activeFilter === "missing" ? "MISSING KEYS" : "ISSUES TO FIX", activeStorageType !== "all" && ` (${activeStorageType.toUpperCase()})`]
|
|
795
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
796
|
+
style: styles.countBadge,
|
|
797
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
798
|
+
style: styles.countText,
|
|
799
|
+
children: visibleKeys.length
|
|
800
|
+
})
|
|
801
|
+
})]
|
|
802
|
+
}), actionButtonsNode]
|
|
803
|
+
}), selectionBarNode, /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageKeySection.StorageKeySection, {
|
|
804
|
+
title: "",
|
|
805
|
+
count: -1,
|
|
806
|
+
keys: visibleKeys,
|
|
807
|
+
emptyMessage: "",
|
|
808
|
+
isSelectMode: isSelectMode,
|
|
809
|
+
selectedKeys: selectedKeyIds,
|
|
810
|
+
onSelectionChange: handleSelectionChange,
|
|
811
|
+
eventCountByKey: eventCountByKey,
|
|
812
|
+
onViewHistory: onViewHistory,
|
|
813
|
+
onHideKey: key => handleHideKeys([key]),
|
|
814
|
+
onEditKey: setEditingKey,
|
|
815
|
+
onToggleKey: handleToggleKey,
|
|
816
|
+
editBlockedFor: editBlockedFor,
|
|
817
|
+
pinnedKeys: pinnedKeys,
|
|
818
|
+
onTogglePin: onTogglePin
|
|
819
|
+
}), lockedBannerNode]
|
|
820
|
+
}) : emptyStateNode, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
821
|
+
style: styles.techFooter,
|
|
822
|
+
children: "ASYNC STORAGE | MMKV | SECURE STORAGE BACKENDS"
|
|
823
|
+
}), upgradeModalNode]
|
|
824
|
+
}), editingKey ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
825
|
+
style: styles.editorOverlay,
|
|
826
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageKeyEditorScreen.StorageKeyEditorScreen, {
|
|
827
|
+
storageKey: editingKey,
|
|
828
|
+
onSave: raw => handleSaveValue(editingKey, raw),
|
|
829
|
+
onClose: () => setEditingKey(null),
|
|
830
|
+
applySafeAreaInset: applySafeAreaInset
|
|
831
|
+
})
|
|
832
|
+
}) : null]
|
|
833
|
+
});
|
|
700
834
|
}
|
|
701
835
|
const styles = _reactNative.StyleSheet.create({
|
|
836
|
+
/** Measures the space the columns actually get; `flex: 1` so it fills the
|
|
837
|
+
* parent exactly as the bare ScrollView it wraps used to. */
|
|
838
|
+
root: {
|
|
839
|
+
flex: 1,
|
|
840
|
+
minHeight: 0
|
|
841
|
+
},
|
|
842
|
+
/**
|
|
843
|
+
* No background of its own: the tree editor paints an opaque screen, while a
|
|
844
|
+
* scalar key shows only a modal and wants the list visible behind its scrim.
|
|
845
|
+
*/
|
|
846
|
+
editorOverlay: {
|
|
847
|
+
..._sharedUi.absoluteFill,
|
|
848
|
+
zIndex: 10
|
|
849
|
+
},
|
|
702
850
|
scrollContainer: {
|
|
703
851
|
flex: 1,
|
|
704
852
|
backgroundColor: _sharedUi.gameUIColors.background
|
|
@@ -844,7 +992,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
844
992
|
fontSize: 9,
|
|
845
993
|
fontWeight: '700',
|
|
846
994
|
color: _sharedUi.macOSColors.text.muted,
|
|
847
|
-
textTransform:
|
|
995
|
+
textTransform: "uppercase",
|
|
848
996
|
letterSpacing: 1
|
|
849
997
|
},
|
|
850
998
|
instanceNavbarScroll: {
|
|
@@ -914,10 +1062,10 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
914
1062
|
},
|
|
915
1063
|
// Free tier limit banner
|
|
916
1064
|
limitBanner: {
|
|
917
|
-
backgroundColor:
|
|
1065
|
+
backgroundColor: _sharedUi.buoyColors.card,
|
|
918
1066
|
borderRadius: 10,
|
|
919
1067
|
borderWidth: 1,
|
|
920
|
-
borderColor:
|
|
1068
|
+
borderColor: _sharedUi.buoyColors.primary + "40",
|
|
921
1069
|
padding: 12,
|
|
922
1070
|
marginTop: 12
|
|
923
1071
|
},
|
|
@@ -933,12 +1081,12 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
933
1081
|
gap: 8
|
|
934
1082
|
},
|
|
935
1083
|
limitBannerText: {
|
|
936
|
-
color:
|
|
1084
|
+
color: _sharedUi.buoyColors.text,
|
|
937
1085
|
fontSize: 13,
|
|
938
1086
|
fontWeight: "600"
|
|
939
1087
|
},
|
|
940
1088
|
limitBannerSubtext: {
|
|
941
|
-
color:
|
|
1089
|
+
color: _sharedUi.buoyColors.textMuted,
|
|
942
1090
|
fontSize: 11
|
|
943
1091
|
}
|
|
944
1092
|
});
|
|
@@ -431,7 +431,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
431
431
|
marginBottom: 20,
|
|
432
432
|
paddingBottom: 12,
|
|
433
433
|
borderBottomWidth: 1,
|
|
434
|
-
borderBottomColor: "rgba(
|
|
434
|
+
borderBottomColor: "rgba(128, 128, 128, 0.2)"
|
|
435
435
|
},
|
|
436
436
|
headerLeft: {
|
|
437
437
|
gap: 2
|
|
@@ -502,7 +502,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
502
502
|
},
|
|
503
503
|
healthBarBg: {
|
|
504
504
|
height: 6,
|
|
505
|
-
backgroundColor: "rgba(
|
|
505
|
+
backgroundColor: "rgba(128, 128, 128, 0.1)",
|
|
506
506
|
borderRadius: 3,
|
|
507
507
|
overflow: "hidden"
|
|
508
508
|
},
|
|
@@ -520,7 +520,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
520
520
|
..._sharedUi.absoluteFill,
|
|
521
521
|
opacity: 0.1,
|
|
522
522
|
borderWidth: 1,
|
|
523
|
-
borderColor: "rgba(
|
|
523
|
+
borderColor: "rgba(128, 128, 128, 0.2)",
|
|
524
524
|
borderRadius: 3
|
|
525
525
|
},
|
|
526
526
|
// Stats grid
|
|
@@ -637,11 +637,11 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
637
637
|
backendItem: {
|
|
638
638
|
flexDirection: "row",
|
|
639
639
|
alignItems: "center",
|
|
640
|
-
backgroundColor: "rgba(
|
|
640
|
+
backgroundColor: "rgba(128, 128, 128, 0.04)",
|
|
641
641
|
borderRadius: 8,
|
|
642
642
|
padding: 10,
|
|
643
643
|
borderWidth: 1,
|
|
644
|
-
borderColor: "rgba(
|
|
644
|
+
borderColor: "rgba(128, 128, 128, 0.1)"
|
|
645
645
|
},
|
|
646
646
|
backendIcon: {
|
|
647
647
|
width: 24,
|
|
@@ -684,7 +684,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
684
684
|
alignItems: "center",
|
|
685
685
|
paddingTop: 12,
|
|
686
686
|
borderTopWidth: 1,
|
|
687
|
-
borderTopColor: "rgba(
|
|
687
|
+
borderTopColor: "rgba(128, 128, 128, 0.2)"
|
|
688
688
|
},
|
|
689
689
|
bottomStats: {
|
|
690
690
|
flex: 1,
|
|
@@ -706,7 +706,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
706
706
|
bottomDivider: {
|
|
707
707
|
width: 1,
|
|
708
708
|
height: 20,
|
|
709
|
-
backgroundColor: "rgba(
|
|
709
|
+
backgroundColor: "rgba(128, 128, 128, 0.2)"
|
|
710
710
|
},
|
|
711
711
|
// Empty state
|
|
712
712
|
emptyState: {
|
|
@@ -8,8 +8,7 @@ var _react = require("react");
|
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
10
10
|
var _license = require("@buoy-gg/license");
|
|
11
|
-
var
|
|
12
|
-
var _SecureStoreRegistry = require("../utils/SecureStoreRegistry");
|
|
11
|
+
var _deleteStorageKeys = require("../utils/deleteStorageKeys");
|
|
13
12
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
13
|
function SelectionActionBar({
|
|
15
14
|
selectedKeys,
|
|
@@ -69,40 +68,7 @@ function SelectionActionBar({
|
|
|
69
68
|
style: "destructive",
|
|
70
69
|
onPress: async () => {
|
|
71
70
|
try {
|
|
72
|
-
|
|
73
|
-
const asyncKeys = selectedKeys.filter(k => k.storageType === "async");
|
|
74
|
-
const mmkvKeys = selectedKeys.filter(k => k.storageType === "mmkv");
|
|
75
|
-
const secureKeys = selectedKeys.filter(k => k.storageType === "secure");
|
|
76
|
-
|
|
77
|
-
// Delete AsyncStorage keys
|
|
78
|
-
if (asyncKeys.length > 0) {
|
|
79
|
-
await (0, _asyncStorageCompat.removeMany)(asyncKeys.map(k => k.key));
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Delete SecureStore keys (via the registry, which knows each
|
|
83
|
-
// key's keychainService options)
|
|
84
|
-
for (const k of secureKeys) {
|
|
85
|
-
await _SecureStoreRegistry.secureStoreRegistry.deleteValue(k.key);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Delete MMKV keys
|
|
89
|
-
if (mmkvKeys.length > 0) {
|
|
90
|
-
// Group by instance
|
|
91
|
-
const byInstance = {};
|
|
92
|
-
mmkvKeys.forEach(k => {
|
|
93
|
-
const instanceId = k.instanceId || "default";
|
|
94
|
-
if (!byInstance[instanceId]) byInstance[instanceId] = [];
|
|
95
|
-
byInstance[instanceId].push(k.key);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// Delete from each instance
|
|
99
|
-
Object.entries(byInstance).forEach(([instanceId, keys]) => {
|
|
100
|
-
const inst = mmkvInstances.find(i => i.id === instanceId);
|
|
101
|
-
if (inst) {
|
|
102
|
-
keys.forEach(key => inst.instance.delete(key));
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
}
|
|
71
|
+
await (0, _deleteStorageKeys.deleteStorageKeys)(selectedKeys, mmkvInstances);
|
|
106
72
|
onDeleteComplete?.();
|
|
107
73
|
} catch (error) {
|
|
108
74
|
_reactNative.Alert.alert("Error", `Failed to delete keys: ${error}`);
|
|
@@ -93,7 +93,7 @@ function StorageActions({
|
|
|
93
93
|
accessibilityLabel: "Refresh storage",
|
|
94
94
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.RefreshCw, {
|
|
95
95
|
size: 16,
|
|
96
|
-
color: isRefreshing ? "#10B981" :
|
|
96
|
+
color: isRefreshing ? "#10B981" : _sharedUi.buoyColors.textSecondary
|
|
97
97
|
})
|
|
98
98
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CopyButton, {
|
|
99
99
|
value: storageKeys,
|
|
@@ -129,11 +129,11 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
129
129
|
justifyContent: "space-between",
|
|
130
130
|
paddingHorizontal: 12,
|
|
131
131
|
paddingVertical: 8,
|
|
132
|
-
backgroundColor: "rgba(
|
|
132
|
+
backgroundColor: "rgba(128, 128, 128, 0.06)",
|
|
133
133
|
borderRadius: 8,
|
|
134
134
|
marginBottom: 12,
|
|
135
135
|
borderWidth: 1,
|
|
136
|
-
borderColor: "rgba(
|
|
136
|
+
borderColor: "rgba(128, 128, 128, 0.16)"
|
|
137
137
|
},
|
|
138
138
|
leftSection: {
|
|
139
139
|
flexDirection: "row",
|
|
@@ -141,7 +141,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
141
141
|
gap: 8
|
|
142
142
|
},
|
|
143
143
|
keyCount: {
|
|
144
|
-
color:
|
|
144
|
+
color: _sharedUi.buoyColors.textSecondary,
|
|
145
145
|
fontSize: 12,
|
|
146
146
|
fontWeight: "500"
|
|
147
147
|
},
|
|
@@ -165,9 +165,9 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
165
165
|
width: 32,
|
|
166
166
|
height: 32,
|
|
167
167
|
borderRadius: 6,
|
|
168
|
-
backgroundColor: "rgba(
|
|
168
|
+
backgroundColor: "rgba(128, 128, 128, 0.06)",
|
|
169
169
|
borderWidth: 1,
|
|
170
|
-
borderColor: "rgba(
|
|
170
|
+
borderColor: "rgba(128, 128, 128, 0.16)",
|
|
171
171
|
alignItems: "center",
|
|
172
172
|
justifyContent: "center"
|
|
173
173
|
},
|