@buoy-gg/storage 7.0.27 → 7.0.29
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 +51 -1
- package/lib/commonjs/storage/components/SelectionActionBar.js +10 -0
- package/lib/commonjs/storage/components/StorageActionButtons.js +16 -0
- package/lib/commonjs/storage/components/StorageEventActionButton.js +1 -0
- package/lib/commonjs/storage/components/StorageEventCard.js +5 -2
- package/lib/commonjs/storage/components/StorageEventFilterView.js +18 -0
- package/lib/commonjs/storage/components/StorageFilterCards.js +9 -0
- package/lib/commonjs/storage/components/StorageKeyEditorScreen.js +26 -5
- package/lib/commonjs/storage/components/StorageKeyRow.js +51 -2
- package/lib/commonjs/storage/components/StorageKeySection.js +23 -7
- package/lib/commonjs/storage/components/StorageModalWithTabs.js +26 -7
- package/lib/commonjs/storage/components/StorageScalarKeyEditor.js +16 -1
- package/lib/commonjs/storage/components/StorageTypeFilterBar.js +2 -0
- package/lib/commonjs/storage/components/StorageValueEditModal.js +18 -2
- package/lib/commonjs/storage/hooks/useTreeDraft.js +12 -1
- package/lib/commonjs/storage/utils/deleteStorageKeys.js +34 -5
- package/lib/module/storage/components/GameUIStorageBrowser.js +51 -1
- package/lib/module/storage/components/SelectionActionBar.js +10 -0
- package/lib/module/storage/components/StorageActionButtons.js +16 -0
- package/lib/module/storage/components/StorageEventActionButton.js +1 -0
- package/lib/module/storage/components/StorageEventCard.js +5 -2
- package/lib/module/storage/components/StorageEventFilterView.js +18 -0
- package/lib/module/storage/components/StorageFilterCards.js +9 -0
- package/lib/module/storage/components/StorageKeyEditorScreen.js +27 -6
- package/lib/module/storage/components/StorageKeyRow.js +52 -3
- package/lib/module/storage/components/StorageKeySection.js +23 -7
- package/lib/module/storage/components/StorageModalWithTabs.js +26 -7
- package/lib/module/storage/components/StorageScalarKeyEditor.js +16 -1
- package/lib/module/storage/components/StorageTypeFilterBar.js +2 -0
- package/lib/module/storage/components/StorageValueEditModal.js +18 -2
- package/lib/module/storage/hooks/useTreeDraft.js +12 -1
- package/lib/module/storage/utils/deleteStorageKeys.js +34 -5
- 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/StorageActionButtons.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageEventActionButton.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageEventCard.d.ts +5 -0
- package/lib/typescript/storage/components/StorageEventCard.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageEventFilterView.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageFilterCards.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageKeyEditorScreen.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageKeyRow.d.ts +9 -0
- package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageKeySection.d.ts +3 -1
- package/lib/typescript/storage/components/StorageKeySection.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageScalarKeyEditor.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageValueEditModal.d.ts.map +1 -1
- package/lib/typescript/storage/hooks/useTreeDraft.d.ts +9 -1
- package/lib/typescript/storage/hooks/useTreeDraft.d.ts.map +1 -1
- package/lib/typescript/storage/utils/deleteStorageKeys.d.ts +15 -5
- package/lib/typescript/storage/utils/deleteStorageKeys.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
import { useMemo } from "react";
|
|
21
21
|
import { Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
|
22
|
-
import { macOSColors, night, FileJson, PillBadge, useSafeAreaInsets, X } from "@buoy-gg/shared-ui";
|
|
22
|
+
import { macOSColors, night, FileJson, PillBadge, ToolBackground, useSafeAreaInsets, X } from "@buoy-gg/shared-ui";
|
|
23
23
|
import { DataViewer, DataTreeActionDock, getAtPath } from "@buoy-gg/shared-ui/dataViewer";
|
|
24
24
|
import { useKeyEditor } from "../hooks/useKeyEditor";
|
|
25
25
|
import { StorageValueEditModal } from "./StorageValueEditModal";
|
|
@@ -88,7 +88,7 @@ function StorageTreeEditor({
|
|
|
88
88
|
} = editor;
|
|
89
89
|
return /*#__PURE__*/_jsxs(View, {
|
|
90
90
|
style: styles.screen,
|
|
91
|
-
children: [/*#__PURE__*/_jsx(EditorHeader, {
|
|
91
|
+
children: [/*#__PURE__*/_jsx(ToolBackground, {}), /*#__PURE__*/_jsx(EditorHeader, {
|
|
92
92
|
storageKey: storageKey,
|
|
93
93
|
state: draft.isSaving ? "Saving…" : draft.isDirty ? "Draft · unsaved" : "In sync with device",
|
|
94
94
|
dirty: draft.isDirty,
|
|
@@ -107,6 +107,7 @@ function StorageTreeEditor({
|
|
|
107
107
|
children: summarize(draft.value)
|
|
108
108
|
})]
|
|
109
109
|
}), /*#__PURE__*/_jsxs(ScrollView, {
|
|
110
|
+
testID: "buoy-storage-editor-scroll",
|
|
110
111
|
style: styles.treeScroll,
|
|
111
112
|
contentContainerStyle: styles.treeContent,
|
|
112
113
|
keyboardShouldPersistTaps: "handled",
|
|
@@ -124,7 +125,11 @@ function StorageTreeEditor({
|
|
|
124
125
|
,
|
|
125
126
|
showTypeFilter: false,
|
|
126
127
|
onSelectionChange: editor.setSelection,
|
|
127
|
-
selectPath: draft.selectPath
|
|
128
|
+
selectPath: draft.selectPath
|
|
129
|
+
// Its own handle root: the card that opened this editor is still
|
|
130
|
+
// mounted underneath, rendering the same value in its preview tree.
|
|
131
|
+
,
|
|
132
|
+
testIDPrefix: "buoy-storage-editor-row",
|
|
128
133
|
onRequestInlineEdit: sel => editor.openValueEditor(sel.path)
|
|
129
134
|
})
|
|
130
135
|
}), /*#__PURE__*/_jsx(Text, {
|
|
@@ -152,6 +157,8 @@ function StorageTreeEditor({
|
|
|
152
157
|
children: [/*#__PURE__*/_jsx(TouchableOpacity, {
|
|
153
158
|
onPress: draft.discard,
|
|
154
159
|
disabled: draft.isSaving,
|
|
160
|
+
testID: "buoy-storage-editor-discard",
|
|
161
|
+
accessibilityRole: "button",
|
|
155
162
|
accessibilityLabel: "Discard changes",
|
|
156
163
|
style: styles.discardButton,
|
|
157
164
|
children: /*#__PURE__*/_jsx(Text, {
|
|
@@ -161,6 +168,8 @@ function StorageTreeEditor({
|
|
|
161
168
|
}), /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
162
169
|
onPress: editor.saveAndClose,
|
|
163
170
|
disabled: draft.isSaving,
|
|
171
|
+
testID: "buoy-storage-editor-save",
|
|
172
|
+
accessibilityRole: "button",
|
|
164
173
|
accessibilityLabel: "Save changes",
|
|
165
174
|
style: [styles.saveButton, draft.isSaving && styles.saveDisabled],
|
|
166
175
|
children: /*#__PURE__*/_jsx(Text, {
|
|
@@ -196,6 +205,8 @@ function EditorHeader({
|
|
|
196
205
|
style: styles.header,
|
|
197
206
|
children: [/*#__PURE__*/_jsx(TouchableOpacity, {
|
|
198
207
|
onPress: onClose,
|
|
208
|
+
testID: "buoy-storage-editor-close",
|
|
209
|
+
accessibilityRole: "button",
|
|
199
210
|
accessibilityLabel: "Close editor",
|
|
200
211
|
style: styles.headerButton,
|
|
201
212
|
hitSlop: {
|
|
@@ -210,7 +221,13 @@ function EditorHeader({
|
|
|
210
221
|
})
|
|
211
222
|
}), /*#__PURE__*/_jsxs(View, {
|
|
212
223
|
style: styles.headerTitle,
|
|
213
|
-
children: [/*#__PURE__*/_jsx(Text
|
|
224
|
+
children: [/*#__PURE__*/_jsx(Text
|
|
225
|
+
// Which key this editor is pointed at. Worth a handle of its own:
|
|
226
|
+
// the editor is reached by expanding a card in a list of hundreds,
|
|
227
|
+
// and opening it on the wrong one looks exactly like opening it on
|
|
228
|
+
// the right one until a write lands somewhere unexpected.
|
|
229
|
+
, {
|
|
230
|
+
testID: "buoy-storage-editor-key",
|
|
214
231
|
style: styles.headerKey,
|
|
215
232
|
numberOfLines: 1,
|
|
216
233
|
children: storageKey.key
|
|
@@ -220,6 +237,8 @@ function EditorHeader({
|
|
|
220
237
|
})]
|
|
221
238
|
}), /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
222
239
|
onPress: onRaw,
|
|
240
|
+
testID: "buoy-storage-editor-raw",
|
|
241
|
+
accessibilityRole: "button",
|
|
223
242
|
accessibilityLabel: "Edit raw JSON",
|
|
224
243
|
style: styles.headerButton,
|
|
225
244
|
hitSlop: {
|
|
@@ -265,8 +284,10 @@ function storageTypeColor(storageType) {
|
|
|
265
284
|
const styles = StyleSheet.create({
|
|
266
285
|
screen: {
|
|
267
286
|
flex: 1,
|
|
268
|
-
//
|
|
269
|
-
|
|
287
|
+
// Opaque on purpose: transparency here showed the whole key list through
|
|
288
|
+
// the editor, not just the sheet's star field. The screen paints its own
|
|
289
|
+
// ToolBackground instead — see the mount site above.
|
|
290
|
+
backgroundColor: night.color.bg
|
|
270
291
|
},
|
|
271
292
|
header: {
|
|
272
293
|
flexDirection: "row",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { memo } from "react";
|
|
4
4
|
import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
|
|
5
|
-
import { macOSColors, night, CompactRow, TypeBadge, HardDrive, Square, CheckSquare, Edit3, EyeOff, Pin, ExpandedInfoRow, PillBadge } from "@buoy-gg/shared-ui";
|
|
5
|
+
import { macOSColors, night, CompactRow, TypeBadge, HardDrive, Square, CheckSquare, Edit3, EyeOff, Pin, Trash2, ExpandedInfoRow, PillBadge } from "@buoy-gg/shared-ui";
|
|
6
6
|
import { getStorageTypeLabel } from "../utils/storageQueryUtils";
|
|
7
7
|
import { getValueTypeLabel, getValueTypeWithPreview, parseStorageValue } from "../utils/valueType";
|
|
8
8
|
import { DataViewer } from "@buoy-gg/shared-ui/dataViewer";
|
|
@@ -89,6 +89,7 @@ export const StorageKeyRow = /*#__PURE__*/memo(function StorageKeyRow({
|
|
|
89
89
|
onTogglePin,
|
|
90
90
|
onEditKey,
|
|
91
91
|
onToggleKey,
|
|
92
|
+
onDeleteKey,
|
|
92
93
|
editBlockedReason
|
|
93
94
|
}) {
|
|
94
95
|
const canEdit = onEditKey != null && editBlockedReason == null;
|
|
@@ -138,6 +139,9 @@ export const StorageKeyRow = /*#__PURE__*/memo(function StorageKeyRow({
|
|
|
138
139
|
children: String(eventCount)
|
|
139
140
|
}), eventCount > 1 && onViewHistory && /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
140
141
|
onPress: onViewHistory,
|
|
142
|
+
testID: "buoy-storage-key-history",
|
|
143
|
+
accessibilityLabel: `View history for ${storageKey.key}`,
|
|
144
|
+
accessibilityRole: "button",
|
|
141
145
|
style: styles.viewHistoryButton,
|
|
142
146
|
hitSlop: {
|
|
143
147
|
top: 6,
|
|
@@ -217,7 +221,14 @@ export const StorageKeyRow = /*#__PURE__*/memo(function StorageKeyRow({
|
|
|
217
221
|
}) : null, onTogglePin || onHideKey || canEdit ? /*#__PURE__*/_jsxs(View, {
|
|
218
222
|
style: styles.actionRow,
|
|
219
223
|
children: [canEdit ? /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
220
|
-
style: styles.editButton
|
|
224
|
+
style: styles.editButton
|
|
225
|
+
// One handle for both jobs on purpose: this is the card's single
|
|
226
|
+
// "change it" affordance, and which of the two it performs is the
|
|
227
|
+
// key's type, not a different control.
|
|
228
|
+
,
|
|
229
|
+
testID: "buoy-storage-key-edit",
|
|
230
|
+
accessibilityLabel: isBoolean && onToggleKey ? `Toggle ${storageKey.key}` : `Edit ${storageKey.key}`,
|
|
231
|
+
accessibilityRole: "button",
|
|
221
232
|
onPress: () => isBoolean && onToggleKey ? onToggleKey(storageKey) : onEditKey?.(storageKey),
|
|
222
233
|
hitSlop: {
|
|
223
234
|
top: 6,
|
|
@@ -234,6 +245,9 @@ export const StorageKeyRow = /*#__PURE__*/memo(function StorageKeyRow({
|
|
|
234
245
|
})]
|
|
235
246
|
}) : null, onTogglePin ? /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
236
247
|
style: [styles.actionChip, isPinned && styles.actionChipActive],
|
|
248
|
+
testID: "buoy-storage-key-pin",
|
|
249
|
+
accessibilityLabel: isPinned ? `Unpin ${storageKey.key}` : `Pin ${storageKey.key} to top`,
|
|
250
|
+
accessibilityRole: "button",
|
|
237
251
|
onPress: () => onTogglePin(storageKey.key),
|
|
238
252
|
hitSlop: {
|
|
239
253
|
top: 6,
|
|
@@ -253,6 +267,9 @@ export const StorageKeyRow = /*#__PURE__*/memo(function StorageKeyRow({
|
|
|
253
267
|
})]
|
|
254
268
|
}) : null, onHideKey ? /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
255
269
|
style: styles.actionChip,
|
|
270
|
+
testID: "buoy-storage-key-hide",
|
|
271
|
+
accessibilityLabel: `Hide ${storageKey.key} from list`,
|
|
272
|
+
accessibilityRole: "button",
|
|
256
273
|
onPress: () => onHideKey(storageKey),
|
|
257
274
|
hitSlop: {
|
|
258
275
|
top: 6,
|
|
@@ -269,6 +286,27 @@ export const StorageKeyRow = /*#__PURE__*/memo(function StorageKeyRow({
|
|
|
269
286
|
}],
|
|
270
287
|
children: "Hide from list"
|
|
271
288
|
})]
|
|
289
|
+
}) : null, canEdit && onDeleteKey ? /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
290
|
+
style: [styles.actionChip, styles.dangerChip],
|
|
291
|
+
testID: "buoy-storage-key-delete",
|
|
292
|
+
accessibilityLabel: `Delete key ${storageKey.key}`,
|
|
293
|
+
accessibilityRole: "button",
|
|
294
|
+
onPress: () => onDeleteKey(storageKey),
|
|
295
|
+
hitSlop: {
|
|
296
|
+
top: 6,
|
|
297
|
+
bottom: 6,
|
|
298
|
+
left: 6,
|
|
299
|
+
right: 6
|
|
300
|
+
},
|
|
301
|
+
children: [/*#__PURE__*/_jsx(Trash2, {
|
|
302
|
+
size: 12,
|
|
303
|
+
color: night.color.danger
|
|
304
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
305
|
+
style: [styles.actionChipText, {
|
|
306
|
+
color: night.color.danger
|
|
307
|
+
}],
|
|
308
|
+
children: "Delete key"
|
|
309
|
+
})]
|
|
272
310
|
}) : null]
|
|
273
311
|
}) : null]
|
|
274
312
|
});
|
|
@@ -281,6 +319,12 @@ export const StorageKeyRow = /*#__PURE__*/memo(function StorageKeyRow({
|
|
|
281
319
|
// Create checkbox element for select mode
|
|
282
320
|
const selectionCheckbox = isSelectMode ? /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
283
321
|
onPress: handleCheckboxPress,
|
|
322
|
+
testID: `buoy-storage-checkbox-${storageKey.storageType}-${storageKey.key}`,
|
|
323
|
+
accessibilityLabel: `Select ${storageKey.key}`,
|
|
324
|
+
accessibilityRole: "checkbox",
|
|
325
|
+
accessibilityState: {
|
|
326
|
+
checked: isSelected
|
|
327
|
+
},
|
|
284
328
|
style: styles.checkboxContainer,
|
|
285
329
|
hitSlop: {
|
|
286
330
|
top: 8,
|
|
@@ -326,7 +370,9 @@ export const StorageKeyRow = /*#__PURE__*/memo(function StorageKeyRow({
|
|
|
326
370
|
})]
|
|
327
371
|
}),
|
|
328
372
|
showChevron: !isSelectMode,
|
|
329
|
-
onPress: isSelectMode ? handleCheckboxPress : onPress ? () => onPress(storageKey) : undefined
|
|
373
|
+
onPress: isSelectMode ? handleCheckboxPress : onPress ? () => onPress(storageKey) : undefined,
|
|
374
|
+
testID: `buoy-storage-row-${storageKey.storageType}-${storageKey.key}`,
|
|
375
|
+
accessibilityLabel: `${storageKey.storageType} ${storageKey.key}`
|
|
330
376
|
}), eventCount != null && eventCount > 1 && /*#__PURE__*/_jsx(View, {
|
|
331
377
|
style: [styles.absCountBadge, {
|
|
332
378
|
backgroundColor: macOSColors.semantic.warning + "22",
|
|
@@ -452,6 +498,9 @@ const styles = StyleSheet.create({
|
|
|
452
498
|
borderWidth: 1,
|
|
453
499
|
borderColor: night.color.border
|
|
454
500
|
},
|
|
501
|
+
dangerChip: {
|
|
502
|
+
borderColor: night.color.danger + "55"
|
|
503
|
+
},
|
|
455
504
|
actionChipActive: {
|
|
456
505
|
backgroundColor: night.color.accentSoft,
|
|
457
506
|
borderColor: night.color.accentBorderStrong
|
|
@@ -29,17 +29,32 @@ export function StorageKeySection({
|
|
|
29
29
|
onTogglePin,
|
|
30
30
|
onEditKey,
|
|
31
31
|
onToggleKey,
|
|
32
|
+
onDeleteKey,
|
|
32
33
|
editBlockedFor
|
|
33
34
|
}) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Identifies a ROW, not a key name.
|
|
37
|
+
*
|
|
38
|
+
* The same name routinely exists in more than one place — an app that keeps
|
|
39
|
+
* `auth.refreshToken` in both MMKV and the keychain has two rows called
|
|
40
|
+
* that, and they are different values in different stores.
|
|
41
|
+
*/
|
|
40
42
|
const getKeyIdentifier = useCallback(storageKey => {
|
|
41
43
|
return storageKey.instanceId ? `${storageKey.storageType}-${storageKey.instanceId}-${storageKey.key}` : `${storageKey.storageType}-${storageKey.key}`;
|
|
42
44
|
}, []);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Which ROW is expanded — by identifier, not by key name.
|
|
48
|
+
*
|
|
49
|
+
* Keyed by name, tapping one of a pair of same-named rows opened BOTH of
|
|
50
|
+
* them: two cards, two value trees, and two Edit buttons, one of which
|
|
51
|
+
* writes to a store you weren't looking at.
|
|
52
|
+
*/
|
|
53
|
+
const [expandedKey, setExpandedKey] = useState(null);
|
|
54
|
+
const handleKeyPress = useCallback(storageKey => {
|
|
55
|
+
const id = getKeyIdentifier(storageKey);
|
|
56
|
+
setExpandedKey(prev => prev === id ? null : id);
|
|
57
|
+
}, [getKeyIdentifier]);
|
|
43
58
|
if (keys.length === 0 && title === "Required Keys") {
|
|
44
59
|
return /*#__PURE__*/_jsxs(View, {
|
|
45
60
|
style: styles.sectionContainer,
|
|
@@ -76,7 +91,7 @@ export function StorageKeySection({
|
|
|
76
91
|
const uniqueKey = getKeyIdentifier(storageKey);
|
|
77
92
|
return /*#__PURE__*/_jsx(StorageKeyRow, {
|
|
78
93
|
storageKey: storageKey,
|
|
79
|
-
isExpanded: !isSelectMode && expandedKey ===
|
|
94
|
+
isExpanded: !isSelectMode && expandedKey === uniqueKey,
|
|
80
95
|
onPress: handleKeyPress,
|
|
81
96
|
isSelectMode: isSelectMode,
|
|
82
97
|
isSelected: selectedKeys.has(uniqueKey),
|
|
@@ -86,6 +101,7 @@ export function StorageKeySection({
|
|
|
86
101
|
onHideKey: onHideKey,
|
|
87
102
|
onEditKey: onEditKey,
|
|
88
103
|
onToggleKey: onToggleKey,
|
|
104
|
+
onDeleteKey: onDeleteKey,
|
|
89
105
|
editBlockedReason: editBlockedFor?.(storageKey),
|
|
90
106
|
isPinned: pinnedKeys?.has(storageKey.key),
|
|
91
107
|
onTogglePin: onTogglePin
|
|
@@ -545,7 +545,8 @@ export function StorageModalWithTabs({
|
|
|
545
545
|
};
|
|
546
546
|
return /*#__PURE__*/_jsx(StorageEventCard, {
|
|
547
547
|
data: cardData,
|
|
548
|
-
onPress: () => handleRawEventPress(item)
|
|
548
|
+
onPress: () => handleRawEventPress(item),
|
|
549
|
+
testID: `buoy-storage-event-${item.id}`
|
|
549
550
|
});
|
|
550
551
|
}, [handleRawEventPress]);
|
|
551
552
|
if (!visible) return null;
|
|
@@ -582,6 +583,7 @@ export function StorageModalWithTabs({
|
|
|
582
583
|
const ascSortedEvents = [...selectedHistoryConversation.events].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
583
584
|
const newestFirstEvents = [...ascSortedEvents].reverse();
|
|
584
585
|
return /*#__PURE__*/_jsx(FlatList, {
|
|
586
|
+
testID: "buoy-storage-history-list",
|
|
585
587
|
style: styles.flexFill,
|
|
586
588
|
data: newestFirstEvents,
|
|
587
589
|
keyExtractor: item => item.id,
|
|
@@ -599,7 +601,8 @@ export function StorageModalWithTabs({
|
|
|
599
601
|
};
|
|
600
602
|
return /*#__PURE__*/_jsx(StorageEventCard, {
|
|
601
603
|
data: cardData,
|
|
602
|
-
onPress: () => setSelectedHistoryEventIndex(ascIdx >= 0 ? ascIdx : 0)
|
|
604
|
+
onPress: () => setSelectedHistoryEventIndex(ascIdx >= 0 ? ascIdx : 0),
|
|
605
|
+
testID: `buoy-storage-history-event-${item.id}`
|
|
603
606
|
});
|
|
604
607
|
},
|
|
605
608
|
contentContainerStyle: styles.listContent,
|
|
@@ -677,6 +680,7 @@ export function StorageModalWithTabs({
|
|
|
677
680
|
return /*#__PURE__*/_jsxs(View, {
|
|
678
681
|
style: styles.flexFill,
|
|
679
682
|
children: [eventTypeFilterBar, /*#__PURE__*/_jsx(FlatList, {
|
|
683
|
+
testID: "buoy-storage-events-list",
|
|
680
684
|
style: styles.flexFill,
|
|
681
685
|
data: visibleEvents,
|
|
682
686
|
renderItem: renderEventItem,
|
|
@@ -754,6 +758,7 @@ export function StorageModalWithTabs({
|
|
|
754
758
|
setIsSearchActive(false);
|
|
755
759
|
},
|
|
756
760
|
placeholder: "Search storage keys...",
|
|
761
|
+
testID: "buoy-storage-search",
|
|
757
762
|
autoFocus: true,
|
|
758
763
|
onSubmitEditing: () => setIsSearchActive(false),
|
|
759
764
|
returnKeyType: "search",
|
|
@@ -768,6 +773,7 @@ export function StorageModalWithTabs({
|
|
|
768
773
|
label: `Events${filteredEvents.length > 0 ? ` (${filteredEvents.length})` : ""}`
|
|
769
774
|
}],
|
|
770
775
|
activeTab: activeTab,
|
|
776
|
+
testIDPrefix: "buoy-storage-tab",
|
|
771
777
|
onTabChange: tab => {
|
|
772
778
|
setActiveTab(tab);
|
|
773
779
|
setSelectedHistoryKey(null);
|
|
@@ -780,13 +786,18 @@ export function StorageModalWithTabs({
|
|
|
780
786
|
children: [onRefresh && !isSearchActive ? /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
781
787
|
onPress: onRefresh,
|
|
782
788
|
style: styles.iconButton,
|
|
789
|
+
testID: "buoy-storage-refresh",
|
|
783
790
|
accessibilityLabel: "Refresh storage",
|
|
791
|
+
accessibilityRole: "button",
|
|
784
792
|
children: /*#__PURE__*/_jsx(RefreshCw, {
|
|
785
793
|
size: 14,
|
|
786
794
|
color: night.color.textSecondary
|
|
787
795
|
})
|
|
788
796
|
}) : null, /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
789
797
|
onPress: handleToggleFilters,
|
|
798
|
+
testID: "buoy-storage-filters",
|
|
799
|
+
accessibilityLabel: "Storage filters",
|
|
800
|
+
accessibilityRole: "button",
|
|
790
801
|
style: [styles.iconButton, (ignoredPatterns.size > 0 || enabledStorageTypes.size < 3) && styles.activeFilterButton],
|
|
791
802
|
children: /*#__PURE__*/_jsx(Filter, {
|
|
792
803
|
size: 14,
|
|
@@ -795,6 +806,9 @@ export function StorageModalWithTabs({
|
|
|
795
806
|
}), activeTab === "browser" && !isSearchActive && /*#__PURE__*/_jsxs(_Fragment, {
|
|
796
807
|
children: [/*#__PURE__*/_jsx(TouchableOpacity, {
|
|
797
808
|
onPress: () => setIsSearchActive(true),
|
|
809
|
+
testID: "buoy-storage-search-open",
|
|
810
|
+
accessibilityLabel: "Open search",
|
|
811
|
+
accessibilityRole: "button",
|
|
798
812
|
style: styles.iconButton,
|
|
799
813
|
children: /*#__PURE__*/_jsx(Search, {
|
|
800
814
|
size: 14,
|
|
@@ -803,20 +817,24 @@ export function StorageModalWithTabs({
|
|
|
803
817
|
}), /*#__PURE__*/_jsx(ToolbarCopyButton, {
|
|
804
818
|
value: getStorageSnapshot,
|
|
805
819
|
disabled: storageDataRef.current.length === 0,
|
|
806
|
-
buttonStyle: styles.iconButton
|
|
820
|
+
buttonStyle: styles.iconButton,
|
|
821
|
+
testID: "buoy-storage-copy"
|
|
807
822
|
})]
|
|
808
823
|
}), activeTab === "events" && /*#__PURE__*/_jsxs(_Fragment, {
|
|
809
824
|
children: [/*#__PURE__*/_jsx(ToolbarCopyButton, {
|
|
810
825
|
value: getEventsSnapshot,
|
|
811
826
|
disabled: filteredEvents.length === 0,
|
|
812
|
-
buttonStyle: styles.iconButton
|
|
827
|
+
buttonStyle: styles.iconButton,
|
|
828
|
+
testID: "buoy-storage-events-copy"
|
|
813
829
|
}), /*#__PURE__*/_jsx(PowerToggleButton, {
|
|
814
830
|
isEnabled: isListening,
|
|
815
831
|
onToggle: handleToggleListening,
|
|
816
|
-
accessibilityLabel: "Toggle storage event monitoring"
|
|
832
|
+
accessibilityLabel: "Toggle storage event monitoring",
|
|
833
|
+
testID: "buoy-storage-power"
|
|
817
834
|
}), /*#__PURE__*/_jsx(ToolbarClearButton, {
|
|
818
835
|
onPress: handleClearEvents,
|
|
819
|
-
buttonStyle: styles.iconButton
|
|
836
|
+
buttonStyle: styles.iconButton,
|
|
837
|
+
testID: "buoy-storage-clear-events"
|
|
820
838
|
})]
|
|
821
839
|
})]
|
|
822
840
|
})]
|
|
@@ -886,7 +904,8 @@ const styles = StyleSheet.create({
|
|
|
886
904
|
paddingVertical: 8,
|
|
887
905
|
borderBottomWidth: 1,
|
|
888
906
|
borderBottomColor: macOSColors.border.default,
|
|
889
|
-
|
|
907
|
+
// Clear, like Bench — the host's hoisted sky shows through the header.
|
|
908
|
+
backgroundColor: "transparent"
|
|
890
909
|
},
|
|
891
910
|
headerSearchContainer: {
|
|
892
911
|
flex: 1
|
|
@@ -17,6 +17,21 @@ import { useCallback, useState } from "react";
|
|
|
17
17
|
import { Alert } from "react-native";
|
|
18
18
|
import { StorageValueEditModal } from "./StorageValueEditModal";
|
|
19
19
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
20
|
+
/**
|
|
21
|
+
* The text `setStorageValue` should store.
|
|
22
|
+
*
|
|
23
|
+
* A string is stored AS ITSELF — `JSON.stringify` here was adding quotes a
|
|
24
|
+
* plain string never had. AsyncStorage hid it (the browser reads values back
|
|
25
|
+
* through `JSON.parse`, so the tool agreed with itself) but the app's own
|
|
26
|
+
* `getItem` saw `"dark"` where it had written `dark`; MMKV stores strings
|
|
27
|
+
* natively and showed the quotes right in the row, compounding on every edit.
|
|
28
|
+
*
|
|
29
|
+
* Everything else keeps JSON: for a number or a boolean that IS its text, and
|
|
30
|
+
* containers never reach this editor.
|
|
31
|
+
*/
|
|
32
|
+
function serializeScalar(value) {
|
|
33
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
34
|
+
}
|
|
20
35
|
export function StorageScalarKeyEditor({
|
|
21
36
|
storageKey,
|
|
22
37
|
value,
|
|
@@ -27,7 +42,7 @@ export function StorageScalarKeyEditor({
|
|
|
27
42
|
const save = useCallback(next => {
|
|
28
43
|
if (saving) return;
|
|
29
44
|
setSaving(true);
|
|
30
|
-
onSave(
|
|
45
|
+
onSave(serializeScalar(next)).then(onClose).catch(e => {
|
|
31
46
|
setSaving(false);
|
|
32
47
|
Alert.alert("Couldn't save", e instanceof Error ? e.message : String(e));
|
|
33
48
|
});
|
|
@@ -52,6 +52,8 @@ export function StorageTypeFilterBar({
|
|
|
52
52
|
const isActive = active === segment.id;
|
|
53
53
|
const accent = segment.color ?? night.color.accent;
|
|
54
54
|
return /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
55
|
+
testID: `buoy-storage-type-${segment.id}`,
|
|
56
|
+
accessibilityRole: "button",
|
|
55
57
|
accessibilityLabel: `Filter by ${segment.label}`,
|
|
56
58
|
accessibilityState: {
|
|
57
59
|
selected: isActive
|
|
@@ -82,6 +82,8 @@ export function StorageValueEditModal({
|
|
|
82
82
|
style: styles.scrim,
|
|
83
83
|
activeOpacity: 1,
|
|
84
84
|
onPress: busy ? undefined : onCancel,
|
|
85
|
+
testID: "buoy-storage-value-scrim",
|
|
86
|
+
accessibilityRole: "button",
|
|
85
87
|
accessibilityLabel: "Dismiss editor"
|
|
86
88
|
}), /*#__PURE__*/_jsx(View, {
|
|
87
89
|
style: styles.panel,
|
|
@@ -111,6 +113,8 @@ export function StorageValueEditModal({
|
|
|
111
113
|
style: styles.fieldScroll,
|
|
112
114
|
keyboardShouldPersistTaps: "handled",
|
|
113
115
|
children: /*#__PURE__*/_jsx(TextInput, {
|
|
116
|
+
testID: "buoy-storage-value-input",
|
|
117
|
+
accessibilityLabel: "Value",
|
|
114
118
|
value: text,
|
|
115
119
|
onChangeText: setText,
|
|
116
120
|
autoFocus: true,
|
|
@@ -121,8 +125,14 @@ export function StorageValueEditModal({
|
|
|
121
125
|
// Multiline for anything textual: stored values are long more
|
|
122
126
|
// often than they're short, and a single line hides that.
|
|
123
127
|
,
|
|
124
|
-
multiline: mode !== "number"
|
|
125
|
-
|
|
128
|
+
multiline: mode !== "number"
|
|
129
|
+
// ASCII for raw JSON, because iOS Smart Punctuation is ON by
|
|
130
|
+
// default and rewrites the quotes you type as curly ones —
|
|
131
|
+
// which makes the text unparseable, disables Save, and leaves
|
|
132
|
+
// an "invalid JSON" message whose cause is invisible at a
|
|
133
|
+
// glance. An ASCII keyboard doesn't do the substitution.
|
|
134
|
+
,
|
|
135
|
+
keyboardType: mode === "number" ? "numeric" : mode === "raw" ? "ascii-capable" : "default",
|
|
126
136
|
onSubmitEditing: mode === "number" ? commit : undefined,
|
|
127
137
|
placeholder: mode === "raw" ? "{ }" : "value",
|
|
128
138
|
placeholderTextColor: night.color.placeholder,
|
|
@@ -136,6 +146,8 @@ export function StorageValueEditModal({
|
|
|
136
146
|
children: [/*#__PURE__*/_jsx(TouchableOpacity, {
|
|
137
147
|
onPress: onCancel,
|
|
138
148
|
disabled: busy,
|
|
149
|
+
testID: "buoy-storage-value-cancel",
|
|
150
|
+
accessibilityRole: "button",
|
|
139
151
|
accessibilityLabel: "Cancel edit",
|
|
140
152
|
style: styles.cancelButton,
|
|
141
153
|
children: /*#__PURE__*/_jsx(Text, {
|
|
@@ -145,6 +157,8 @@ export function StorageValueEditModal({
|
|
|
145
157
|
}), mode === "boolean" ? null : /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
146
158
|
onPress: commit,
|
|
147
159
|
disabled: blocked,
|
|
160
|
+
testID: "buoy-storage-value-save",
|
|
161
|
+
accessibilityRole: "button",
|
|
148
162
|
accessibilityLabel: saveLabel,
|
|
149
163
|
style: [styles.saveButton, blocked && styles.saveDisabled],
|
|
150
164
|
children: /*#__PURE__*/_jsx(Text, {
|
|
@@ -165,6 +179,8 @@ function BooleanChoice({
|
|
|
165
179
|
style: styles.boolRow,
|
|
166
180
|
children: [true, false].map(option => /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
167
181
|
onPress: () => onPick(option),
|
|
182
|
+
testID: `buoy-storage-value-${option}`,
|
|
183
|
+
accessibilityRole: "button",
|
|
168
184
|
accessibilityLabel: `Set ${option}`,
|
|
169
185
|
style: [styles.boolButton, current === option && styles.boolActive],
|
|
170
186
|
children: /*#__PURE__*/_jsx(Text, {
|
|
@@ -62,12 +62,23 @@ export function useTreeDraft(liveValue, save) {
|
|
|
62
62
|
const selectAt = useCallback(path => {
|
|
63
63
|
setSelectPath(path);
|
|
64
64
|
}, []);
|
|
65
|
+
|
|
66
|
+
/** Leave edit mode entirely. Only correct on the way out (after a write). */
|
|
65
67
|
const reset = useCallback(() => {
|
|
66
68
|
setIsEditing(false);
|
|
67
69
|
setDraft(undefined);
|
|
68
70
|
setSelectPath(undefined);
|
|
69
71
|
setError(null);
|
|
70
72
|
}, []);
|
|
73
|
+
|
|
74
|
+
/** Re-seed the draft from what's stored, staying in edit mode. */
|
|
75
|
+
const discard = useCallback(() => {
|
|
76
|
+
setDraft(liveValue);
|
|
77
|
+
setBaseline(JSON.stringify(liveValue));
|
|
78
|
+
setSelectPath(undefined);
|
|
79
|
+
setError(null);
|
|
80
|
+
setIsEditing(true);
|
|
81
|
+
}, [liveValue]);
|
|
71
82
|
const commit = useCallback(async () => {
|
|
72
83
|
if (!isDirty || !save) {
|
|
73
84
|
reset();
|
|
@@ -98,6 +109,6 @@ export function useTreeDraft(liveValue, save) {
|
|
|
98
109
|
apply,
|
|
99
110
|
selectAt,
|
|
100
111
|
commit,
|
|
101
|
-
discard
|
|
112
|
+
discard
|
|
102
113
|
};
|
|
103
114
|
}
|
|
@@ -5,10 +5,15 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Each backend removes keys differently — AsyncStorage takes a batch,
|
|
7
7
|
* SecureStore has to go through the registry (only it knows each key's
|
|
8
|
-
* `keychainService` options), and MMKV deletes per registered instance.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* `keychainService` options), and MMKV deletes per registered instance. A
|
|
9
|
+
* second copy of that fan-out is exactly how one backend quietly stops being
|
|
10
|
+
* cleaned up — which is not hypothetical: the MMKV branch called a method
|
|
11
|
+
* react-native-mmkv v4 had renamed, and deleting an MMKV key silently did
|
|
12
|
+
* nothing until an e2e test deleted from all three backends at once.
|
|
13
|
+
*
|
|
14
|
+
* One call site today: the selection action bar. Deleting is deliberately not
|
|
15
|
+
* an affordance on the row itself — see `StorageKeyRow`, whose expanded card
|
|
16
|
+
* carries three actions and only one of them changes anything.
|
|
12
17
|
*
|
|
13
18
|
* Pro gating and confirmation are deliberately NOT here: they belong to the UI
|
|
14
19
|
* that has the user's attention. This function assumes the caller already asked.
|
|
@@ -16,6 +21,30 @@
|
|
|
16
21
|
|
|
17
22
|
import { removeMany } from "./asyncStorageCompat";
|
|
18
23
|
import { secureStoreRegistry } from "./SecureStoreRegistry";
|
|
24
|
+
/**
|
|
25
|
+
* Remove one key from an MMKV instance, whichever version it is.
|
|
26
|
+
*
|
|
27
|
+
* react-native-mmkv v4 renamed `delete(key)` to `remove(key)`. Calling the old
|
|
28
|
+
* name on a v4 instance throws, and because the callers wrap deletion in a
|
|
29
|
+
* try/catch that only surfaces an alert, the visible result was a key that
|
|
30
|
+
* refused to delete — the same shape as a permissions problem or a read-only
|
|
31
|
+
* instance, and nothing to point at the real cause.
|
|
32
|
+
*
|
|
33
|
+
* `storageSyncAdapter` and `snapshotProvider` already did this; this path was
|
|
34
|
+
* the one that missed it.
|
|
35
|
+
*/
|
|
36
|
+
function removeMMKVKey(instance, key) {
|
|
37
|
+
if (typeof instance.remove === "function") {
|
|
38
|
+
instance.remove(key);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (typeof instance.delete === "function") {
|
|
42
|
+
instance.delete(key);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
throw new Error("MMKV instance exposes neither remove() nor delete()");
|
|
46
|
+
}
|
|
47
|
+
|
|
19
48
|
/**
|
|
20
49
|
* Removes every key from whichever backend holds it. Rejects on the first
|
|
21
50
|
* failure — callers surface that, rather than reporting a partial delete as
|
|
@@ -42,7 +71,7 @@ export async function deleteStorageKeys(keys, mmkvInstances) {
|
|
|
42
71
|
Object.entries(byInstance).forEach(([instanceId, instanceKeys]) => {
|
|
43
72
|
const inst = mmkvInstances.find(i => i.id === instanceId);
|
|
44
73
|
if (inst) {
|
|
45
|
-
instanceKeys.forEach(key => inst.instance
|
|
74
|
+
instanceKeys.forEach(key => removeMMKVKey(inst.instance, key));
|
|
46
75
|
}
|
|
47
76
|
});
|
|
48
77
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GameUIStorageBrowser.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/GameUIStorageBrowser.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,gBAAgB,EACjB,MAAM,OAAO,CAAC;AAWf,OAAO,EAAkB,kBAAkB,EAAmB,MAAM,UAAU,CAAC;AAK/E,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAC;AA2C9B;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QAAmC,CAAC;AAEpE,UAAU,yBAAyB;IACjC,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC3C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,mBAAmB,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC;IACvD;;;;OAIG;IACH,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC3D,mFAAmF;IACnF,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE;QAC9B,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;KACrB,KAAK,IAAI,CAAC;IACX,yCAAyC;IACzC,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,kCAAkC;IAClC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,yBAAyB,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC9D,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,oBAAoB,CAAC,EACnC,mBAAwB,EACxB,WAAmB,EACnB,eAA0C,EAC1C,eAAe,EACf,YAAY,EACZ,WAAgB,EAChB,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,GACnB,EAAE,yBAAyB,+
|
|
1
|
+
{"version":3,"file":"GameUIStorageBrowser.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/GameUIStorageBrowser.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,gBAAgB,EACjB,MAAM,OAAO,CAAC;AAWf,OAAO,EAAkB,kBAAkB,EAAmB,MAAM,UAAU,CAAC;AAK/E,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAC;AA2C9B;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QAAmC,CAAC;AAEpE,UAAU,yBAAyB;IACjC,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC3C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,mBAAmB,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC;IACvD;;;;OAIG;IACH,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC3D,mFAAmF;IACnF,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE;QAC9B,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;KACrB,KAAK,IAAI,CAAC;IACX,yCAAyC;IACzC,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,kCAAkC;IAClC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,yBAAyB,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC9D,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,oBAAoB,CAAC,EACnC,mBAAwB,EACxB,WAAmB,EACnB,eAA0C,EAC1C,eAAe,EACf,YAAY,EACZ,WAAgB,EAChB,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,GACnB,EAAE,yBAAyB,+BA0hC3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectionActionBar.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/SelectionActionBar.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,UAAU,uBAAuB;IAC/B,4BAA4B;IAC5B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,kCAAkC;IAClC,aAAa,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IACpD,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,gEAAgE;IAChE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IAC9C,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,mCAAmC;IACnC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,gBAAgB,GACjB,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"SelectionActionBar.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/SelectionActionBar.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,UAAU,uBAAuB;IAC/B,4BAA4B;IAC5B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,kCAAkC;IAClC,aAAa,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IACpD,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,gEAAgE;IAChE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IAC9C,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,mCAAmC;IACnC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,gBAAgB,GACjB,EAAE,uBAAuB,sCA6IzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageActionButtons.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/StorageActionButtons.tsx"],"names":[],"mappings":"AAOA,UAAU,yBAAyB;IACjC,iCAAiC;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IACrD,iBAAiB,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IACxD,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,uCAAuC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wCAAwC;IACxC,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,+BAA+B;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,aAAkB,EAClB,iBAAyB,EACzB,eAAe,EACf,YAAoB,EACpB,kBAAkB,EAClB,aAAiB,GAClB,EAAE,yBAAyB,+
|
|
1
|
+
{"version":3,"file":"StorageActionButtons.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/StorageActionButtons.tsx"],"names":[],"mappings":"AAOA,UAAU,yBAAyB;IACjC,iCAAiC;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IACrD,iBAAiB,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IACxD,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,uCAAuC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wCAAwC;IACxC,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,+BAA+B;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,aAAkB,EAClB,iBAAyB,EACzB,eAAe,EACf,YAAoB,EACpB,kBAAkB,EAClB,aAAiB,GAClB,EAAE,yBAAyB,+BA0O3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageEventActionButton.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/StorageEventActionButton.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;CAmBlB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,aAAa,CAAC;AAE3D,UAAU,6BAA6B;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,QAAgB,EAChB,MAAc,GACf,EAAE,6BAA6B,+
|
|
1
|
+
{"version":3,"file":"StorageEventActionButton.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/StorageEventActionButton.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;CAmBlB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,aAAa,CAAC;AAE3D,UAAU,6BAA6B;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,QAAgB,EAChB,MAAc,GACf,EAAE,6BAA6B,+BA8C/B"}
|
|
@@ -30,6 +30,11 @@ interface StorageEventCardProps {
|
|
|
30
30
|
data: StorageEventCardData;
|
|
31
31
|
/** Called when the card is pressed */
|
|
32
32
|
onPress: () => void;
|
|
33
|
+
/**
|
|
34
|
+
* Automation handle. The caller supplies it because the same key appears on
|
|
35
|
+
* many events — only the caller knows the event's own id.
|
|
36
|
+
*/
|
|
37
|
+
testID?: string;
|
|
33
38
|
/** Whether this card is selected */
|
|
34
39
|
isSelected?: boolean;
|
|
35
40
|
/** Whether to show chevron */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageEventCard.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/StorageEventCard.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,oCAAoC;AACpC,MAAM,MAAM,gBAAgB,GACxB,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,MAAM,GACN,WAAW,GACX,QAAQ,GACR,OAAO,CAAC;AAEZ;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAU7D;AAED,MAAM,WAAW,oBAAoB;IACnC,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kCAAkC;IAClC,kBAAkB,EAAE,IAAI,CAAC;IACzB,uCAAuC;IACvC,YAAY,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;IACpC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED,UAAU,qBAAqB;IAC7B,4BAA4B;IAC5B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,sCAAsC;IACtC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,oCAAoC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAsDD,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"StorageEventCard.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/StorageEventCard.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,oCAAoC;AACpC,MAAM,MAAM,gBAAgB,GACxB,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,MAAM,GACN,WAAW,GACX,QAAQ,GACR,OAAO,CAAC;AAEZ;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAU7D;AAED,MAAM,WAAW,oBAAoB;IACnC,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kCAAkC;IAClC,kBAAkB,EAAE,IAAI,CAAC;IACzB,uCAAuC;IACvC,YAAY,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;IACpC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED,UAAU,qBAAqB;IAC7B,4BAA4B;IAC5B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,sCAAsC;IACtC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAsDD,eAAO,MAAM,gBAAgB,6DAgC3B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageEventFilterView.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/StorageEventFilterView.tsx"],"names":[],"mappings":"AAYA,UAAU,2BAA2B;IACnC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,mBAAmB,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC;IACtD,mBAAmB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,KAAK,IAAI,CAAC;CAClE;AAED,wBAAgB,sBAAsB,CAAC,EACrC,eAAe,EACf,eAAe,EACf,YAAY,EACZ,aAAkB,EAClB,mBAAmB,EACnB,mBAAmB,GACpB,EAAE,2BAA2B,+
|
|
1
|
+
{"version":3,"file":"StorageEventFilterView.d.ts","sourceRoot":"","sources":["../../../../src/storage/components/StorageEventFilterView.tsx"],"names":[],"mappings":"AAYA,UAAU,2BAA2B;IACnC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,mBAAmB,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC;IACtD,mBAAmB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,KAAK,IAAI,CAAC;CAClE;AAED,wBAAgB,sBAAsB,CAAC,EACrC,eAAe,EACf,eAAe,EACf,YAAY,EACZ,aAAkB,EAClB,mBAAmB,EACnB,mBAAmB,GACpB,EAAE,2BAA2B,+BA4H7B"}
|