react-native-storage-inspector 1.0.2 → 1.0.3
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/README.md +5 -6
- package/dist/index.d.mts +56 -86
- package/dist/index.d.ts +56 -86
- package/dist/index.js +669 -755
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +650 -736
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React7, { useState, useMemo, useEffect, useCallback } from 'react';
|
|
2
2
|
import { StyleSheet, Dimensions, View, ScrollView, RefreshControl, Text, TouchableOpacity, Share, Modal, TextInput } from 'react-native';
|
|
3
3
|
|
|
4
4
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
@@ -35,7 +35,6 @@ function createMMKVAdapter(instance, name) {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
// src/adapters/async-storage.ts
|
|
38
|
-
var asyncStorage = null;
|
|
39
38
|
function getAsyncStorageFromRequire() {
|
|
40
39
|
try {
|
|
41
40
|
const mod = require("@react-native-async-storage/async-storage");
|
|
@@ -44,8 +43,8 @@ function getAsyncStorageFromRequire() {
|
|
|
44
43
|
return null;
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
|
-
function createAsyncStorageAdapter(
|
|
48
|
-
const getStorage = () =>
|
|
46
|
+
function createAsyncStorageAdapter() {
|
|
47
|
+
const getStorage = () => getAsyncStorageFromRequire();
|
|
49
48
|
return {
|
|
50
49
|
type: "async-storage",
|
|
51
50
|
name: "Async Storage",
|
|
@@ -76,7 +75,6 @@ function createAsyncStorageAdapter(instance) {
|
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
// src/adapters/keychain.ts
|
|
79
|
-
var keychain = null;
|
|
80
78
|
function getKeychainFromRequire() {
|
|
81
79
|
try {
|
|
82
80
|
return require("react-native-keychain");
|
|
@@ -84,14 +82,14 @@ function getKeychainFromRequire() {
|
|
|
84
82
|
return null;
|
|
85
83
|
}
|
|
86
84
|
}
|
|
87
|
-
function createKeychainAdapter(
|
|
88
|
-
const getKc = () =>
|
|
85
|
+
function createKeychainAdapter() {
|
|
86
|
+
const getKc = () => getKeychainFromRequire();
|
|
89
87
|
return {
|
|
90
88
|
type: "keychain",
|
|
91
89
|
name: "Keychain",
|
|
92
90
|
async getAllKeys() {
|
|
93
91
|
const kc = getKc();
|
|
94
|
-
if (!kc) return [
|
|
92
|
+
if (!kc) return [];
|
|
95
93
|
const genericServices = [];
|
|
96
94
|
if (typeof kc.getAllGenericPasswordServices === "function") {
|
|
97
95
|
try {
|
|
@@ -100,42 +98,32 @@ function createKeychainAdapter(knownKeys = [], instance) {
|
|
|
100
98
|
} catch {
|
|
101
99
|
}
|
|
102
100
|
}
|
|
103
|
-
|
|
104
|
-
return Array.from(merged);
|
|
101
|
+
return genericServices;
|
|
105
102
|
},
|
|
106
103
|
async getItem(key) {
|
|
107
104
|
const kc = getKc();
|
|
108
|
-
if (!kc) return null;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return creds2.password;
|
|
114
|
-
}
|
|
115
|
-
} catch {
|
|
105
|
+
if (!kc?.getGenericPassword) return null;
|
|
106
|
+
try {
|
|
107
|
+
const creds = await kc.getGenericPassword({ service: key });
|
|
108
|
+
if (creds && typeof creds === "object" && "password" in creds) {
|
|
109
|
+
return creds.password;
|
|
116
110
|
}
|
|
111
|
+
} catch {
|
|
117
112
|
}
|
|
118
|
-
|
|
119
|
-
return creds?.password ?? null;
|
|
113
|
+
return null;
|
|
120
114
|
},
|
|
121
115
|
async setItem(key, value) {
|
|
122
116
|
const kc = getKc();
|
|
123
|
-
if (!kc)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (result2 === false) throw new Error("Keychain set failed");
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
const result = await kc.setInternetCredentials(key, key, value);
|
|
117
|
+
if (!kc?.setGenericPassword)
|
|
118
|
+
throw new Error("react-native-keychain is not available");
|
|
119
|
+
const result = await kc.setGenericPassword(key, value, { service: key });
|
|
130
120
|
if (result === false) throw new Error("Keychain set failed");
|
|
131
121
|
},
|
|
132
122
|
async removeItem(key) {
|
|
133
123
|
const kc = getKc();
|
|
134
|
-
if (!kc)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
await kc.resetInternetCredentials(key);
|
|
124
|
+
if (!kc?.resetGenericPassword)
|
|
125
|
+
throw new Error("react-native-keychain is not available");
|
|
126
|
+
await kc.resetGenericPassword({ service: key });
|
|
139
127
|
},
|
|
140
128
|
isAvailable() {
|
|
141
129
|
return getKc() !== null;
|
|
@@ -143,8 +131,20 @@ function createKeychainAdapter(knownKeys = [], instance) {
|
|
|
143
131
|
};
|
|
144
132
|
}
|
|
145
133
|
|
|
134
|
+
// src/utils.ts
|
|
135
|
+
function parsePersistedKeys(raw) {
|
|
136
|
+
if (raw == null || raw === "") return [];
|
|
137
|
+
try {
|
|
138
|
+
const parsed = JSON.parse(raw);
|
|
139
|
+
if (!Array.isArray(parsed)) return [];
|
|
140
|
+
return parsed.filter((item) => typeof item === "string");
|
|
141
|
+
} catch {
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
146
|
// src/adapters/secure-store.ts
|
|
147
|
-
var
|
|
147
|
+
var PERSISTED_KEYS_STORAGE_KEY = "__storage_inspector_secure_store_keys__";
|
|
148
148
|
function getSecureStoreFromRequire() {
|
|
149
149
|
try {
|
|
150
150
|
return require("expo-secure-store");
|
|
@@ -152,13 +152,17 @@ function getSecureStoreFromRequire() {
|
|
|
152
152
|
return null;
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
-
function createSecureStoreAdapter(knownKeys = []
|
|
156
|
-
const getStore = () =>
|
|
155
|
+
function createSecureStoreAdapter(knownKeys = []) {
|
|
156
|
+
const getStore = () => getSecureStoreFromRequire();
|
|
157
157
|
return {
|
|
158
158
|
type: "expo-secure-store",
|
|
159
159
|
name: "Secure Store",
|
|
160
160
|
async getAllKeys() {
|
|
161
|
-
|
|
161
|
+
const store = getStore();
|
|
162
|
+
if (!store) return [];
|
|
163
|
+
const persistedKeysString = await store.getItemAsync(PERSISTED_KEYS_STORAGE_KEY);
|
|
164
|
+
const persistedKeys = parsePersistedKeys(persistedKeysString);
|
|
165
|
+
return [.../* @__PURE__ */ new Set([...knownKeys, ...persistedKeys])];
|
|
162
166
|
},
|
|
163
167
|
async getItem(key) {
|
|
164
168
|
const store = getStore();
|
|
@@ -169,11 +173,26 @@ function createSecureStoreAdapter(knownKeys = [], instance) {
|
|
|
169
173
|
const store = getStore();
|
|
170
174
|
if (!store) throw new Error("expo-secure-store is not available");
|
|
171
175
|
await store.setItemAsync(key, value);
|
|
176
|
+
if (key === PERSISTED_KEYS_STORAGE_KEY) return;
|
|
177
|
+
const persistedKeysString = await store.getItemAsync(PERSISTED_KEYS_STORAGE_KEY);
|
|
178
|
+
const persistedKeys = parsePersistedKeys(persistedKeysString);
|
|
179
|
+
const newPersistedKeys = [.../* @__PURE__ */ new Set([...persistedKeys, key])];
|
|
180
|
+
await store.setItemAsync(
|
|
181
|
+
PERSISTED_KEYS_STORAGE_KEY,
|
|
182
|
+
JSON.stringify(newPersistedKeys)
|
|
183
|
+
);
|
|
172
184
|
},
|
|
173
185
|
async removeItem(key) {
|
|
174
186
|
const store = getStore();
|
|
175
187
|
if (!store) throw new Error("expo-secure-store is not available");
|
|
176
188
|
await store.deleteItemAsync(key);
|
|
189
|
+
const persistedKeysString = await store.getItemAsync(PERSISTED_KEYS_STORAGE_KEY);
|
|
190
|
+
const persistedKeys = parsePersistedKeys(persistedKeysString);
|
|
191
|
+
const newPersistedKeys = persistedKeys.filter((k) => k !== key);
|
|
192
|
+
await store.setItemAsync(
|
|
193
|
+
PERSISTED_KEYS_STORAGE_KEY,
|
|
194
|
+
JSON.stringify(newPersistedKeys)
|
|
195
|
+
);
|
|
177
196
|
},
|
|
178
197
|
isAvailable() {
|
|
179
198
|
return getStore() !== null;
|
|
@@ -197,7 +216,8 @@ function useStorageItems(adapter) {
|
|
|
197
216
|
const pairs = [];
|
|
198
217
|
for (const key of keys) {
|
|
199
218
|
const value = await adapter.getItem(key);
|
|
200
|
-
|
|
219
|
+
if (value === null) continue;
|
|
220
|
+
pairs.push({ key, value });
|
|
201
221
|
}
|
|
202
222
|
setItems(pairs);
|
|
203
223
|
} catch (e) {
|
|
@@ -224,7 +244,8 @@ var theme = {
|
|
|
224
244
|
text: "#000000",
|
|
225
245
|
textSecondary: "#666666",
|
|
226
246
|
textMuted: "#999999",
|
|
227
|
-
inverted: "#ffffff"
|
|
247
|
+
inverted: "#ffffff",
|
|
248
|
+
overlayBackdrop: "rgba(0,0,0,0.5)"
|
|
228
249
|
}
|
|
229
250
|
};
|
|
230
251
|
|
|
@@ -245,15 +266,11 @@ var ROTATION = {
|
|
|
245
266
|
chevronDown: "90deg",
|
|
246
267
|
chevronUp: "-90deg"
|
|
247
268
|
};
|
|
248
|
-
function Icon({
|
|
249
|
-
name,
|
|
250
|
-
size = 20,
|
|
251
|
-
tintColor = theme.colors.text,
|
|
252
|
-
iconStyle
|
|
253
|
-
}) {
|
|
269
|
+
function Icon(props) {
|
|
270
|
+
const { name, size = 20, tintColor = theme.colors.text, iconStyle } = props;
|
|
254
271
|
const glyph = GLYPHS[name] ?? "?";
|
|
255
272
|
const rotation = ROTATION[name];
|
|
256
|
-
return /* @__PURE__ */
|
|
273
|
+
return /* @__PURE__ */ React7.createElement(
|
|
257
274
|
Text,
|
|
258
275
|
{
|
|
259
276
|
style: [
|
|
@@ -276,7 +293,6 @@ var { width: SCREEN_WIDTH } = Dimensions.get("window");
|
|
|
276
293
|
var LAYOUT = {
|
|
277
294
|
padding: 16,
|
|
278
295
|
fontSize: 14,
|
|
279
|
-
headerHeight: 52,
|
|
280
296
|
rowMinHeight: 48,
|
|
281
297
|
sectionHeaderHeight: 48,
|
|
282
298
|
iconSize: 20,
|
|
@@ -290,331 +306,242 @@ var LAYOUT = {
|
|
|
290
306
|
sectionRadius: 4,
|
|
291
307
|
screenWidth: SCREEN_WIDTH
|
|
292
308
|
};
|
|
293
|
-
|
|
309
|
+
|
|
310
|
+
// src/components/IconButton.tsx
|
|
311
|
+
function IconButton(props) {
|
|
312
|
+
const {
|
|
313
|
+
name,
|
|
314
|
+
onPress,
|
|
315
|
+
size = LAYOUT.iconSize,
|
|
316
|
+
tintColor = theme.colors.text,
|
|
317
|
+
disabled = false,
|
|
318
|
+
hitSlop = LAYOUT.hitSlop,
|
|
319
|
+
style,
|
|
320
|
+
activeOpacity = 0.6
|
|
321
|
+
} = props;
|
|
322
|
+
return /* @__PURE__ */ React7.createElement(
|
|
323
|
+
TouchableOpacity,
|
|
324
|
+
{
|
|
325
|
+
style: [styles2.iconButton, style],
|
|
326
|
+
onPress,
|
|
327
|
+
disabled,
|
|
328
|
+
hitSlop,
|
|
329
|
+
activeOpacity
|
|
330
|
+
},
|
|
331
|
+
/* @__PURE__ */ React7.createElement(
|
|
332
|
+
Icon,
|
|
333
|
+
{
|
|
334
|
+
name,
|
|
335
|
+
size,
|
|
336
|
+
tintColor: disabled ? theme.colors.textMuted : tintColor
|
|
337
|
+
}
|
|
338
|
+
)
|
|
339
|
+
);
|
|
340
|
+
}
|
|
294
341
|
var styles2 = StyleSheet.create({
|
|
295
|
-
|
|
342
|
+
iconButton: {
|
|
343
|
+
width: LAYOUT.iconButtonSize,
|
|
344
|
+
height: LAYOUT.iconButtonSize,
|
|
345
|
+
alignItems: "center",
|
|
346
|
+
justifyContent: "center"
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
// src/strings.ts
|
|
351
|
+
var strings = {
|
|
352
|
+
// StorageInspector
|
|
353
|
+
noAdapterAvailable: "No storage adapter available. Install at least one of: react-native-mmkv, @react-native-async-storage/async-storage, react-native-keychain, expo-secure-store",
|
|
354
|
+
// StorageSection
|
|
355
|
+
keychainHint: "No generic password items yet. Add a key using + above.",
|
|
356
|
+
secureStoreHint: "Secure Store has no list API. Pass secureStoreKeys prop with known keys, or add a key using + above.",
|
|
357
|
+
loading: "Loading\u2026",
|
|
358
|
+
noItems: "No items",
|
|
359
|
+
valueLabel: "Value",
|
|
360
|
+
charCount: (n) => n === 1 ? "1 char" : `${n} chars`,
|
|
361
|
+
deleteItemTitle: (key) => `Delete ${key}?`,
|
|
362
|
+
deleteItemMessage: (key) => `This will permanently delete the ${key} storage item. Do you wish to continue?`,
|
|
363
|
+
clearAllTitle: (name) => `Clear All ${name}?`,
|
|
364
|
+
clearAllMessage: (count, name) => `This will permanently delete all ${count} ${name} items. Do you wish to continue?`,
|
|
365
|
+
// StorageList
|
|
366
|
+
storageNotAvailable: "This storage is not available.",
|
|
367
|
+
keychainHintShort: "No items yet. Add a key below.",
|
|
368
|
+
edit: "Edit",
|
|
369
|
+
delete: "Delete",
|
|
370
|
+
addItem: "Add item",
|
|
371
|
+
// ItemForm
|
|
372
|
+
keyRequired: "Key is required",
|
|
373
|
+
saveFailed: "Save failed",
|
|
374
|
+
editItemTitle: (key) => `Edit ${key}`,
|
|
375
|
+
addItemTitle: (storageName) => `Add ${storageName} Item`,
|
|
376
|
+
storageTypeLabel: (name) => `Storage Type: ${name}`,
|
|
377
|
+
keyLabel: "Key",
|
|
378
|
+
enterKeyPlaceholder: "Enter key",
|
|
379
|
+
enterValuePlaceholder: "Enter value",
|
|
380
|
+
cancel: "Cancel",
|
|
381
|
+
saving: "Saving\u2026",
|
|
382
|
+
save: "Save",
|
|
383
|
+
add: "Add",
|
|
384
|
+
// ConfirmModal defaults
|
|
385
|
+
confirmDelete: "Yes, delete",
|
|
386
|
+
cancelKeep: "No, keep it"
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
// src/components/ItemForm.tsx
|
|
390
|
+
function ItemForm(props) {
|
|
391
|
+
const { visible, storageName, editingItem, onSave, onCancel } = props;
|
|
392
|
+
const [key, setKey] = useState("");
|
|
393
|
+
const [value, setValue] = useState("");
|
|
394
|
+
const [saving, setSaving] = useState(false);
|
|
395
|
+
const [error, setError] = useState(null);
|
|
396
|
+
const isEdit = editingItem !== null;
|
|
397
|
+
useEffect(() => {
|
|
398
|
+
if (visible) {
|
|
399
|
+
setKey(editingItem?.key ?? "");
|
|
400
|
+
setValue(editingItem?.value ?? "");
|
|
401
|
+
setError(null);
|
|
402
|
+
}
|
|
403
|
+
}, [visible, editingItem]);
|
|
404
|
+
const handleSubmit = async () => {
|
|
405
|
+
const k = key.trim();
|
|
406
|
+
if (!k) {
|
|
407
|
+
setError(strings.keyRequired);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
setSaving(true);
|
|
411
|
+
setError(null);
|
|
412
|
+
try {
|
|
413
|
+
await onSave(k, value);
|
|
414
|
+
onCancel();
|
|
415
|
+
} catch (e) {
|
|
416
|
+
setError(e instanceof Error ? e.message : strings.saveFailed);
|
|
417
|
+
} finally {
|
|
418
|
+
setSaving(false);
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
const title = isEdit ? strings.editItemTitle(editingItem?.key ?? "") : strings.addItemTitle(storageName);
|
|
422
|
+
return /* @__PURE__ */ React7.createElement(Modal, { visible, transparent: true, animationType: "slide", onRequestClose: onCancel }, /* @__PURE__ */ React7.createElement(View, { style: styles3.formOverlay }, /* @__PURE__ */ React7.createElement(
|
|
423
|
+
TouchableOpacity,
|
|
424
|
+
{
|
|
425
|
+
style: { flex: 1, width: "100%" },
|
|
426
|
+
activeOpacity: 1,
|
|
427
|
+
onPress: onCancel
|
|
428
|
+
}
|
|
429
|
+
), /* @__PURE__ */ React7.createElement(View, { style: styles3.formModal }, /* @__PURE__ */ React7.createElement(View, { style: styles3.formHeader }, /* @__PURE__ */ React7.createElement(Text, { style: styles3.formTitle, numberOfLines: 1 }, title), /* @__PURE__ */ React7.createElement(
|
|
430
|
+
IconButton,
|
|
431
|
+
{
|
|
432
|
+
name: "close",
|
|
433
|
+
onPress: onCancel,
|
|
434
|
+
size: 24,
|
|
435
|
+
tintColor: theme.colors.textSecondary,
|
|
436
|
+
style: styles3.formCloseButton,
|
|
437
|
+
hitSlop: LAYOUT.hitSlopLarge
|
|
438
|
+
}
|
|
439
|
+
)), /* @__PURE__ */ React7.createElement(Text, { style: styles3.formStorageType }, strings.storageTypeLabel(storageName)), /* @__PURE__ */ React7.createElement(Text, { style: styles3.formLabel }, strings.keyLabel), /* @__PURE__ */ React7.createElement(
|
|
440
|
+
TextInput,
|
|
441
|
+
{
|
|
442
|
+
style: [styles3.formInput, isEdit && styles3.formInputDisabled],
|
|
443
|
+
value: key,
|
|
444
|
+
onChangeText: setKey,
|
|
445
|
+
placeholder: strings.enterKeyPlaceholder,
|
|
446
|
+
placeholderTextColor: theme.colors.textMuted,
|
|
447
|
+
editable: !isEdit,
|
|
448
|
+
autoCapitalize: "none",
|
|
449
|
+
multiline: true
|
|
450
|
+
}
|
|
451
|
+
), /* @__PURE__ */ React7.createElement(Text, { style: styles3.formLabel }, strings.valueLabel), /* @__PURE__ */ React7.createElement(
|
|
452
|
+
TextInput,
|
|
453
|
+
{
|
|
454
|
+
style: styles3.formInput,
|
|
455
|
+
value,
|
|
456
|
+
onChangeText: setValue,
|
|
457
|
+
placeholder: strings.enterValuePlaceholder,
|
|
458
|
+
placeholderTextColor: theme.colors.textMuted,
|
|
459
|
+
multiline: true,
|
|
460
|
+
numberOfLines: 3
|
|
461
|
+
}
|
|
462
|
+
), error ? /* @__PURE__ */ React7.createElement(Text, { style: [styles3.errorText, { marginBottom: 12 }] }, error) : null, /* @__PURE__ */ React7.createElement(View, { style: styles3.formActions }, /* @__PURE__ */ React7.createElement(
|
|
463
|
+
TouchableOpacity,
|
|
464
|
+
{
|
|
465
|
+
style: [styles3.formButton, styles3.formButtonCancel],
|
|
466
|
+
onPress: onCancel,
|
|
467
|
+
disabled: saving
|
|
468
|
+
},
|
|
469
|
+
/* @__PURE__ */ React7.createElement(Text, { style: [styles3.formButtonText, styles3.formButtonTextCancel] }, strings.cancel)
|
|
470
|
+
), /* @__PURE__ */ React7.createElement(
|
|
471
|
+
TouchableOpacity,
|
|
472
|
+
{
|
|
473
|
+
style: [styles3.formButton, styles3.formButtonSubmit],
|
|
474
|
+
onPress: handleSubmit,
|
|
475
|
+
disabled: saving
|
|
476
|
+
},
|
|
477
|
+
/* @__PURE__ */ React7.createElement(Text, { style: [styles3.formButtonText, styles3.formButtonTextSubmit] }, saving ? strings.saving : isEdit ? strings.save : strings.add)
|
|
478
|
+
)))));
|
|
479
|
+
}
|
|
480
|
+
var { colors } = theme;
|
|
481
|
+
var styles3 = StyleSheet.create({
|
|
482
|
+
formOverlay: {
|
|
296
483
|
flex: 1,
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
content: {
|
|
301
|
-
flex: 1
|
|
484
|
+
backgroundColor: colors.overlayBackdrop,
|
|
485
|
+
justifyContent: "flex-end",
|
|
486
|
+
alignItems: "center"
|
|
302
487
|
},
|
|
303
|
-
|
|
304
|
-
|
|
488
|
+
formModal: {
|
|
489
|
+
width: "100%",
|
|
490
|
+
maxWidth: LAYOUT.screenWidth,
|
|
491
|
+
backgroundColor: colors.background,
|
|
492
|
+
borderTopLeftRadius: LAYOUT.modalRadius,
|
|
493
|
+
borderTopRightRadius: LAYOUT.modalRadius,
|
|
494
|
+
padding: LAYOUT.padding,
|
|
495
|
+
paddingBottom: LAYOUT.padding + 34
|
|
305
496
|
},
|
|
306
|
-
|
|
307
|
-
height: LAYOUT.headerHeight,
|
|
497
|
+
formHeader: {
|
|
308
498
|
flexDirection: "row",
|
|
309
499
|
alignItems: "center",
|
|
310
500
|
justifyContent: "space-between",
|
|
311
|
-
|
|
312
|
-
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
313
|
-
borderBottomColor: colors.border,
|
|
314
|
-
backgroundColor: colors.background
|
|
315
|
-
},
|
|
316
|
-
headerLeft: {
|
|
317
|
-
minWidth: 44,
|
|
318
|
-
alignItems: "flex-start"
|
|
319
|
-
},
|
|
320
|
-
headerCenter: {
|
|
321
|
-
flex: 1,
|
|
322
|
-
alignItems: "center",
|
|
323
|
-
justifyContent: "center"
|
|
324
|
-
},
|
|
325
|
-
headerRight: {
|
|
326
|
-
minWidth: 44,
|
|
327
|
-
alignItems: "flex-end"
|
|
328
|
-
},
|
|
329
|
-
sectionHeaderLabelWrap: {
|
|
330
|
-
flex: 1
|
|
501
|
+
marginBottom: LAYOUT.padding
|
|
331
502
|
},
|
|
332
|
-
|
|
503
|
+
formTitle: {
|
|
333
504
|
fontSize: 17,
|
|
334
505
|
fontWeight: "600",
|
|
335
|
-
color: colors.text
|
|
506
|
+
color: colors.text,
|
|
507
|
+
flex: 1
|
|
336
508
|
},
|
|
337
|
-
|
|
509
|
+
formCloseButton: {
|
|
338
510
|
width: 44,
|
|
339
511
|
height: 44,
|
|
340
|
-
alignItems: "
|
|
512
|
+
alignItems: "flex-end",
|
|
341
513
|
justifyContent: "center"
|
|
342
514
|
},
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
},
|
|
348
|
-
sectionHeader: {
|
|
349
|
-
height: LAYOUT.sectionHeaderHeight,
|
|
350
|
-
flexDirection: "row",
|
|
351
|
-
alignItems: "center",
|
|
352
|
-
paddingHorizontal: LAYOUT.padding,
|
|
353
|
-
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
354
|
-
borderBottomColor: colors.border,
|
|
355
|
-
backgroundColor: colors.backgroundSecondary,
|
|
356
|
-
marginTop: LAYOUT.padding,
|
|
357
|
-
marginHorizontal: LAYOUT.padding,
|
|
358
|
-
borderRadius: LAYOUT.sectionRadius
|
|
515
|
+
formStorageType: {
|
|
516
|
+
fontSize: 13,
|
|
517
|
+
color: colors.textSecondary,
|
|
518
|
+
marginBottom: 12
|
|
359
519
|
},
|
|
360
|
-
|
|
361
|
-
fontSize:
|
|
520
|
+
formLabel: {
|
|
521
|
+
fontSize: 12,
|
|
362
522
|
fontWeight: "600",
|
|
363
|
-
color: colors.text
|
|
364
|
-
},
|
|
365
|
-
sectionHeaderCount: {
|
|
366
523
|
color: colors.textSecondary,
|
|
367
|
-
|
|
524
|
+
marginBottom: 6
|
|
368
525
|
},
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
526
|
+
formInput: {
|
|
527
|
+
borderWidth: 1,
|
|
528
|
+
borderColor: colors.border,
|
|
529
|
+
borderRadius: 10,
|
|
530
|
+
padding: 12,
|
|
531
|
+
fontSize: LAYOUT.fontSize,
|
|
532
|
+
marginBottom: LAYOUT.padding,
|
|
533
|
+
color: colors.text,
|
|
534
|
+
backgroundColor: colors.background
|
|
373
535
|
},
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
alignItems: "center",
|
|
378
|
-
justifyContent: "center"
|
|
536
|
+
formInputDisabled: {
|
|
537
|
+
backgroundColor: colors.backgroundSecondary,
|
|
538
|
+
color: colors.textSecondary
|
|
379
539
|
},
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
},
|
|
386
|
-
itemRow: {
|
|
387
|
-
minHeight: LAYOUT.rowMinHeight,
|
|
388
|
-
paddingHorizontal: LAYOUT.padding,
|
|
389
|
-
paddingVertical: 12,
|
|
390
|
-
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
391
|
-
borderBottomColor: colors.borderLight,
|
|
392
|
-
backgroundColor: colors.background,
|
|
393
|
-
marginHorizontal: LAYOUT.padding,
|
|
394
|
-
marginBottom: 4
|
|
395
|
-
},
|
|
396
|
-
itemRowCollapsed: {
|
|
397
|
-
flexDirection: "row",
|
|
398
|
-
alignItems: "center",
|
|
399
|
-
alignSelf: "stretch"
|
|
400
|
-
},
|
|
401
|
-
itemKey: {
|
|
402
|
-
flex: 1,
|
|
403
|
-
fontSize: LAYOUT.fontSize,
|
|
404
|
-
fontWeight: "500",
|
|
405
|
-
color: colors.text
|
|
406
|
-
},
|
|
407
|
-
itemChars: {
|
|
408
|
-
fontSize: 12,
|
|
409
|
-
color: colors.textSecondary,
|
|
410
|
-
marginTop: 2
|
|
411
|
-
},
|
|
412
|
-
itemRowActions: {
|
|
413
|
-
flexDirection: "row",
|
|
414
|
-
alignItems: "center",
|
|
415
|
-
marginLeft: LAYOUT.iconGap,
|
|
416
|
-
gap: LAYOUT.iconGap
|
|
417
|
-
},
|
|
418
|
-
itemRowExpanded: {
|
|
419
|
-
paddingTop: 4
|
|
420
|
-
},
|
|
421
|
-
valueBox: {
|
|
422
|
-
backgroundColor: colors.backgroundSecondary,
|
|
423
|
-
borderRadius: 8,
|
|
424
|
-
padding: 12,
|
|
425
|
-
marginTop: 8,
|
|
426
|
-
marginBottom: 8,
|
|
427
|
-
borderWidth: StyleSheet.hairlineWidth,
|
|
428
|
-
borderColor: colors.border
|
|
429
|
-
},
|
|
430
|
-
valueBoxLabel: {
|
|
431
|
-
fontSize: 11,
|
|
432
|
-
fontWeight: "600",
|
|
433
|
-
color: colors.textSecondary,
|
|
434
|
-
marginBottom: 4,
|
|
435
|
-
textTransform: "uppercase"
|
|
436
|
-
},
|
|
437
|
-
valueBoxText: {
|
|
438
|
-
fontSize: LAYOUT.fontSize,
|
|
439
|
-
color: colors.text
|
|
440
|
-
},
|
|
441
|
-
empty: {
|
|
442
|
-
padding: LAYOUT.padding * 2,
|
|
443
|
-
alignItems: "center",
|
|
444
|
-
marginHorizontal: LAYOUT.padding
|
|
445
|
-
},
|
|
446
|
-
emptyText: {
|
|
447
|
-
fontSize: LAYOUT.fontSize,
|
|
448
|
-
color: colors.textMuted
|
|
449
|
-
},
|
|
450
|
-
loading: {
|
|
451
|
-
padding: LAYOUT.padding * 2,
|
|
452
|
-
alignItems: "center",
|
|
453
|
-
marginHorizontal: LAYOUT.padding
|
|
454
|
-
},
|
|
455
|
-
loadingText: {
|
|
456
|
-
fontSize: LAYOUT.fontSize,
|
|
457
|
-
color: colors.textSecondary
|
|
458
|
-
},
|
|
459
|
-
error: {
|
|
460
|
-
padding: LAYOUT.padding,
|
|
461
|
-
backgroundColor: colors.backgroundTertiary,
|
|
462
|
-
marginHorizontal: LAYOUT.padding,
|
|
463
|
-
marginVertical: 8,
|
|
464
|
-
borderRadius: 8
|
|
465
|
-
},
|
|
466
|
-
errorText: {
|
|
467
|
-
fontSize: LAYOUT.fontSize,
|
|
468
|
-
color: colors.text
|
|
469
|
-
},
|
|
470
|
-
keychainHint: {
|
|
471
|
-
padding: LAYOUT.padding,
|
|
472
|
-
marginHorizontal: LAYOUT.padding,
|
|
473
|
-
marginTop: 8,
|
|
474
|
-
marginBottom: 4,
|
|
475
|
-
backgroundColor: colors.backgroundSecondary,
|
|
476
|
-
borderRadius: 8
|
|
477
|
-
},
|
|
478
|
-
keychainHintText: {
|
|
479
|
-
fontSize: LAYOUT.fontSize - 1,
|
|
480
|
-
color: colors.textSecondary
|
|
481
|
-
},
|
|
482
|
-
list: {
|
|
483
|
-
flex: 1
|
|
484
|
-
},
|
|
485
|
-
listContent: {
|
|
486
|
-
flexGrow: 1,
|
|
487
|
-
paddingBottom: LAYOUT.fabSize + LAYOUT.padding + 20
|
|
488
|
-
},
|
|
489
|
-
row: {
|
|
490
|
-
flexDirection: "row",
|
|
491
|
-
alignItems: "center",
|
|
492
|
-
minHeight: LAYOUT.rowMinHeight,
|
|
493
|
-
paddingHorizontal: LAYOUT.padding,
|
|
494
|
-
paddingVertical: 12,
|
|
495
|
-
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
496
|
-
borderBottomColor: colors.borderLight,
|
|
497
|
-
backgroundColor: colors.background,
|
|
498
|
-
marginHorizontal: LAYOUT.padding
|
|
499
|
-
},
|
|
500
|
-
rowKey: {
|
|
501
|
-
flex: 1,
|
|
502
|
-
fontSize: LAYOUT.fontSize,
|
|
503
|
-
fontWeight: "500",
|
|
504
|
-
color: colors.text
|
|
505
|
-
},
|
|
506
|
-
rowValue: {
|
|
507
|
-
fontSize: LAYOUT.fontSize - 1,
|
|
508
|
-
color: colors.textSecondary
|
|
509
|
-
},
|
|
510
|
-
rowActions: {
|
|
511
|
-
flexDirection: "row",
|
|
512
|
-
alignItems: "center",
|
|
513
|
-
marginLeft: LAYOUT.iconGap,
|
|
514
|
-
gap: LAYOUT.iconGap
|
|
515
|
-
},
|
|
516
|
-
rowButton: {
|
|
517
|
-
paddingVertical: 8,
|
|
518
|
-
paddingHorizontal: 12
|
|
519
|
-
},
|
|
520
|
-
rowButtonText: {
|
|
521
|
-
fontSize: 14,
|
|
522
|
-
fontWeight: "600",
|
|
523
|
-
color: colors.text
|
|
524
|
-
},
|
|
525
|
-
rowButtonDanger: {
|
|
526
|
-
color: colors.text
|
|
527
|
-
},
|
|
528
|
-
addButton: {
|
|
529
|
-
position: "absolute",
|
|
530
|
-
bottom: LAYOUT.padding + 16,
|
|
531
|
-
right: LAYOUT.padding + 16,
|
|
532
|
-
width: LAYOUT.fabSize,
|
|
533
|
-
height: LAYOUT.fabSize,
|
|
534
|
-
borderRadius: LAYOUT.fabSize / 2,
|
|
535
|
-
backgroundColor: colors.text,
|
|
536
|
-
alignItems: "center",
|
|
537
|
-
justifyContent: "center"
|
|
538
|
-
},
|
|
539
|
-
addButtonText: {
|
|
540
|
-
fontSize: 16,
|
|
541
|
-
fontWeight: "600",
|
|
542
|
-
color: colors.inverted
|
|
543
|
-
},
|
|
544
|
-
fab: {
|
|
545
|
-
position: "absolute",
|
|
546
|
-
bottom: LAYOUT.padding + 16,
|
|
547
|
-
right: LAYOUT.padding + 16,
|
|
548
|
-
width: LAYOUT.fabSize,
|
|
549
|
-
height: LAYOUT.fabSize,
|
|
550
|
-
borderRadius: LAYOUT.fabSize / 2,
|
|
551
|
-
backgroundColor: colors.text,
|
|
552
|
-
alignItems: "center",
|
|
553
|
-
justifyContent: "center"
|
|
554
|
-
},
|
|
555
|
-
formOverlay: {
|
|
556
|
-
flex: 1,
|
|
557
|
-
backgroundColor: "rgba(0,0,0,0.5)",
|
|
558
|
-
justifyContent: "flex-end",
|
|
559
|
-
alignItems: "center"
|
|
560
|
-
},
|
|
561
|
-
formModal: {
|
|
562
|
-
width: "100%",
|
|
563
|
-
maxWidth: LAYOUT.screenWidth,
|
|
564
|
-
backgroundColor: colors.background,
|
|
565
|
-
borderTopLeftRadius: LAYOUT.modalRadius,
|
|
566
|
-
borderTopRightRadius: LAYOUT.modalRadius,
|
|
567
|
-
padding: LAYOUT.padding,
|
|
568
|
-
paddingBottom: LAYOUT.padding + 34
|
|
569
|
-
},
|
|
570
|
-
formHeader: {
|
|
571
|
-
flexDirection: "row",
|
|
572
|
-
alignItems: "center",
|
|
573
|
-
justifyContent: "space-between",
|
|
574
|
-
marginBottom: LAYOUT.padding
|
|
575
|
-
},
|
|
576
|
-
formTitle: {
|
|
577
|
-
fontSize: 17,
|
|
578
|
-
fontWeight: "600",
|
|
579
|
-
color: colors.text,
|
|
580
|
-
flex: 1
|
|
581
|
-
},
|
|
582
|
-
formCloseButton: {
|
|
583
|
-
width: 44,
|
|
584
|
-
height: 44,
|
|
585
|
-
alignItems: "flex-end",
|
|
586
|
-
justifyContent: "center"
|
|
587
|
-
},
|
|
588
|
-
formStorageType: {
|
|
589
|
-
fontSize: 13,
|
|
590
|
-
color: colors.textSecondary,
|
|
591
|
-
marginBottom: 12
|
|
592
|
-
},
|
|
593
|
-
formLabel: {
|
|
594
|
-
fontSize: 12,
|
|
595
|
-
fontWeight: "600",
|
|
596
|
-
color: colors.textSecondary,
|
|
597
|
-
marginBottom: 6
|
|
598
|
-
},
|
|
599
|
-
formInput: {
|
|
600
|
-
borderWidth: 1,
|
|
601
|
-
borderColor: colors.border,
|
|
602
|
-
borderRadius: 10,
|
|
603
|
-
padding: 12,
|
|
604
|
-
fontSize: LAYOUT.fontSize,
|
|
605
|
-
marginBottom: LAYOUT.padding,
|
|
606
|
-
color: colors.text,
|
|
607
|
-
backgroundColor: colors.background
|
|
608
|
-
},
|
|
609
|
-
formInputDisabled: {
|
|
610
|
-
backgroundColor: colors.backgroundSecondary,
|
|
611
|
-
color: colors.textSecondary
|
|
612
|
-
},
|
|
613
|
-
formActions: {
|
|
614
|
-
flexDirection: "row",
|
|
615
|
-
justifyContent: "flex-end",
|
|
616
|
-
gap: 12,
|
|
617
|
-
marginTop: 8
|
|
540
|
+
formActions: {
|
|
541
|
+
flexDirection: "row",
|
|
542
|
+
justifyContent: "flex-end",
|
|
543
|
+
gap: 12,
|
|
544
|
+
marginTop: 8
|
|
618
545
|
},
|
|
619
546
|
formButton: {
|
|
620
547
|
paddingVertical: 12,
|
|
@@ -641,16 +568,79 @@ var styles2 = StyleSheet.create({
|
|
|
641
568
|
formButtonTextSubmit: {
|
|
642
569
|
color: colors.inverted
|
|
643
570
|
},
|
|
571
|
+
errorText: {
|
|
572
|
+
fontSize: LAYOUT.fontSize,
|
|
573
|
+
color: colors.text
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
function ConfirmModal(props) {
|
|
577
|
+
const {
|
|
578
|
+
visible,
|
|
579
|
+
title,
|
|
580
|
+
message,
|
|
581
|
+
confirmLabel = strings.confirmDelete,
|
|
582
|
+
cancelLabel = strings.cancelKeep,
|
|
583
|
+
danger = true,
|
|
584
|
+
onConfirm,
|
|
585
|
+
onCancel
|
|
586
|
+
} = props;
|
|
587
|
+
return /* @__PURE__ */ React7.createElement(Modal, { visible, transparent: true, animationType: "slide", onRequestClose: onCancel }, /* @__PURE__ */ React7.createElement(View, { style: styles4.confirmOverlay }, /* @__PURE__ */ React7.createElement(
|
|
588
|
+
TouchableOpacity,
|
|
589
|
+
{
|
|
590
|
+
style: { flex: 1, width: "100%" },
|
|
591
|
+
activeOpacity: 1,
|
|
592
|
+
onPress: onCancel
|
|
593
|
+
}
|
|
594
|
+
), /* @__PURE__ */ React7.createElement(View, { style: styles4.confirmModal }, /* @__PURE__ */ React7.createElement(View, { style: styles4.confirmHeader }, /* @__PURE__ */ React7.createElement(Text, { style: styles4.confirmTitle }, title), /* @__PURE__ */ React7.createElement(
|
|
595
|
+
IconButton,
|
|
596
|
+
{
|
|
597
|
+
name: "close",
|
|
598
|
+
onPress: onCancel,
|
|
599
|
+
size: 24,
|
|
600
|
+
tintColor: theme.colors.textSecondary,
|
|
601
|
+
style: styles4.formCloseButton,
|
|
602
|
+
hitSlop: LAYOUT.hitSlopLarge
|
|
603
|
+
}
|
|
604
|
+
)), /* @__PURE__ */ React7.createElement(Text, { style: styles4.confirmMessage }, message), /* @__PURE__ */ React7.createElement(View, { style: styles4.confirmActions }, /* @__PURE__ */ React7.createElement(
|
|
605
|
+
TouchableOpacity,
|
|
606
|
+
{
|
|
607
|
+
style: [styles4.confirmButton, styles4.confirmButtonSecondary],
|
|
608
|
+
onPress: onCancel
|
|
609
|
+
},
|
|
610
|
+
/* @__PURE__ */ React7.createElement(Text, { style: [styles4.confirmButtonText, styles4.confirmButtonTextSecondary] }, cancelLabel)
|
|
611
|
+
), /* @__PURE__ */ React7.createElement(
|
|
612
|
+
TouchableOpacity,
|
|
613
|
+
{
|
|
614
|
+
style: [
|
|
615
|
+
styles4.confirmButton,
|
|
616
|
+
danger ? styles4.confirmButtonDanger : styles4.formButtonSubmit
|
|
617
|
+
],
|
|
618
|
+
onPress: onConfirm
|
|
619
|
+
},
|
|
620
|
+
/* @__PURE__ */ React7.createElement(
|
|
621
|
+
Text,
|
|
622
|
+
{
|
|
623
|
+
style: [
|
|
624
|
+
styles4.confirmButtonText,
|
|
625
|
+
danger ? styles4.confirmButtonTextDanger : styles4.formButtonTextSubmit
|
|
626
|
+
]
|
|
627
|
+
},
|
|
628
|
+
confirmLabel
|
|
629
|
+
)
|
|
630
|
+
)))));
|
|
631
|
+
}
|
|
632
|
+
var { colors: colors2 } = theme;
|
|
633
|
+
var styles4 = StyleSheet.create({
|
|
644
634
|
confirmOverlay: {
|
|
645
635
|
flex: 1,
|
|
646
|
-
backgroundColor:
|
|
636
|
+
backgroundColor: colors2.overlayBackdrop,
|
|
647
637
|
justifyContent: "flex-end",
|
|
648
638
|
alignItems: "center"
|
|
649
639
|
},
|
|
650
640
|
confirmModal: {
|
|
651
641
|
width: "100%",
|
|
652
642
|
maxWidth: LAYOUT.screenWidth,
|
|
653
|
-
backgroundColor:
|
|
643
|
+
backgroundColor: colors2.background,
|
|
654
644
|
borderTopLeftRadius: LAYOUT.modalRadius,
|
|
655
645
|
borderTopRightRadius: LAYOUT.modalRadius,
|
|
656
646
|
padding: LAYOUT.padding,
|
|
@@ -665,12 +655,18 @@ var styles2 = StyleSheet.create({
|
|
|
665
655
|
confirmTitle: {
|
|
666
656
|
fontSize: 17,
|
|
667
657
|
fontWeight: "600",
|
|
668
|
-
color:
|
|
658
|
+
color: colors2.text,
|
|
669
659
|
flex: 1
|
|
670
660
|
},
|
|
661
|
+
formCloseButton: {
|
|
662
|
+
width: 44,
|
|
663
|
+
height: 44,
|
|
664
|
+
alignItems: "flex-end",
|
|
665
|
+
justifyContent: "center"
|
|
666
|
+
},
|
|
671
667
|
confirmMessage: {
|
|
672
668
|
fontSize: 15,
|
|
673
|
-
color:
|
|
669
|
+
color: colors2.textSecondary,
|
|
674
670
|
lineHeight: 22,
|
|
675
671
|
marginBottom: 20
|
|
676
672
|
},
|
|
@@ -686,278 +682,171 @@ var styles2 = StyleSheet.create({
|
|
|
686
682
|
},
|
|
687
683
|
confirmButtonSecondary: {
|
|
688
684
|
backgroundColor: "transparent",
|
|
689
|
-
borderWidth: 1,
|
|
690
|
-
borderColor:
|
|
691
|
-
},
|
|
692
|
-
confirmButtonDanger: {
|
|
693
|
-
backgroundColor:
|
|
694
|
-
},
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
},
|
|
702
|
-
|
|
703
|
-
color:
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
disabled,
|
|
724
|
-
hitSlop,
|
|
725
|
-
activeOpacity
|
|
726
|
-
},
|
|
727
|
-
/* @__PURE__ */ React6.createElement(
|
|
728
|
-
Icon,
|
|
729
|
-
{
|
|
730
|
-
name,
|
|
731
|
-
size,
|
|
732
|
-
tintColor: disabled ? theme.colors.textMuted : tintColor
|
|
733
|
-
}
|
|
734
|
-
)
|
|
735
|
-
);
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
// src/strings.ts
|
|
739
|
-
var strings = {
|
|
740
|
-
// StorageInspector
|
|
741
|
-
noAdapterAvailable: "No storage adapter available. Install at least one of: react-native-mmkv, @react-native-async-storage/async-storage, react-native-keychain, expo-secure-store",
|
|
742
|
-
// StorageSection
|
|
743
|
-
keychainHint: "No generic password items yet. Add a key using + above, or pass keychainKeys for internet credentials.",
|
|
744
|
-
secureStoreHint: "Secure Store has no list API. Pass secureStoreKeys prop with known keys, or add a key using + above.",
|
|
745
|
-
loading: "Loading\u2026",
|
|
746
|
-
noItems: "No items",
|
|
747
|
-
valueLabel: "Value",
|
|
748
|
-
emptyValue: "(empty)",
|
|
749
|
-
charCount: (n) => n === 1 ? "1 char" : `${n} chars`,
|
|
750
|
-
deleteItemTitle: (key) => `Delete ${key}?`,
|
|
751
|
-
deleteItemMessage: (key) => `This will permanently delete the ${key} storage item. Do you wish to continue?`,
|
|
752
|
-
clearAllTitle: (name) => `Clear All ${name}?`,
|
|
753
|
-
clearAllMessage: (count, name) => `This will permanently delete all ${count} ${name} items. Do you wish to continue?`,
|
|
754
|
-
// StorageList
|
|
755
|
-
storageNotAvailable: "This storage is not available.",
|
|
756
|
-
keychainHintShort: "No items yet. Add a key below, or pass keychainKeys for internet credentials.",
|
|
757
|
-
edit: "Edit",
|
|
758
|
-
delete: "Delete",
|
|
759
|
-
addItem: "Add item",
|
|
760
|
-
// ItemForm
|
|
761
|
-
keyRequired: "Key is required",
|
|
762
|
-
saveFailed: "Save failed",
|
|
763
|
-
editItemTitle: (key) => `Edit ${key}`,
|
|
764
|
-
addItemTitle: (storageName) => `Add ${storageName} Item`,
|
|
765
|
-
storageTypeLabel: (name) => `Storage Type: ${name}`,
|
|
766
|
-
keyLabel: "Key",
|
|
767
|
-
enterKeyPlaceholder: "Enter key",
|
|
768
|
-
enterValuePlaceholder: "Enter value",
|
|
769
|
-
cancel: "Cancel",
|
|
770
|
-
saving: "Saving\u2026",
|
|
771
|
-
save: "Save",
|
|
772
|
-
add: "Add",
|
|
773
|
-
// ConfirmModal defaults
|
|
774
|
-
confirmDelete: "Yes, delete",
|
|
775
|
-
cancelKeep: "No, keep it"
|
|
776
|
-
};
|
|
777
|
-
|
|
778
|
-
// src/components/ItemForm.tsx
|
|
779
|
-
function ItemForm({
|
|
780
|
-
visible,
|
|
781
|
-
storageName,
|
|
782
|
-
editingItem,
|
|
783
|
-
onSave,
|
|
784
|
-
onCancel
|
|
785
|
-
}) {
|
|
786
|
-
const [key, setKey] = useState("");
|
|
787
|
-
const [value, setValue] = useState("");
|
|
788
|
-
const [saving, setSaving] = useState(false);
|
|
789
|
-
const [error, setError] = useState(null);
|
|
790
|
-
const isEdit = editingItem !== null;
|
|
791
|
-
useEffect(() => {
|
|
792
|
-
if (visible) {
|
|
793
|
-
setKey(editingItem?.key ?? "");
|
|
794
|
-
setValue(editingItem?.value ?? "");
|
|
795
|
-
setError(null);
|
|
796
|
-
}
|
|
797
|
-
}, [visible, editingItem]);
|
|
798
|
-
const handleSubmit = async () => {
|
|
799
|
-
const k = key.trim();
|
|
800
|
-
if (!k) {
|
|
801
|
-
setError(strings.keyRequired);
|
|
802
|
-
return;
|
|
803
|
-
}
|
|
804
|
-
setSaving(true);
|
|
805
|
-
setError(null);
|
|
806
|
-
try {
|
|
807
|
-
await onSave(k, value);
|
|
808
|
-
onCancel();
|
|
809
|
-
} catch (e) {
|
|
810
|
-
setError(e instanceof Error ? e.message : strings.saveFailed);
|
|
811
|
-
} finally {
|
|
812
|
-
setSaving(false);
|
|
813
|
-
}
|
|
814
|
-
};
|
|
815
|
-
const title = isEdit ? strings.editItemTitle(editingItem?.key ?? "") : strings.addItemTitle(storageName);
|
|
816
|
-
return /* @__PURE__ */ React6.createElement(Modal, { visible, transparent: true, animationType: "slide", onRequestClose: onCancel }, /* @__PURE__ */ React6.createElement(View, { style: styles2.formOverlay }, /* @__PURE__ */ React6.createElement(
|
|
817
|
-
TouchableOpacity,
|
|
818
|
-
{
|
|
819
|
-
style: { flex: 1, width: "100%" },
|
|
820
|
-
activeOpacity: 1,
|
|
821
|
-
onPress: onCancel
|
|
822
|
-
}
|
|
823
|
-
), /* @__PURE__ */ React6.createElement(View, { style: styles2.formModal }, /* @__PURE__ */ React6.createElement(View, { style: styles2.formHeader }, /* @__PURE__ */ React6.createElement(Text, { style: styles2.formTitle, numberOfLines: 1 }, title), /* @__PURE__ */ React6.createElement(
|
|
824
|
-
IconButton,
|
|
825
|
-
{
|
|
826
|
-
name: "close",
|
|
827
|
-
onPress: onCancel,
|
|
828
|
-
size: 24,
|
|
829
|
-
tintColor: theme.colors.textSecondary,
|
|
830
|
-
style: styles2.formCloseButton,
|
|
831
|
-
hitSlop: LAYOUT.hitSlopLarge
|
|
832
|
-
}
|
|
833
|
-
)), /* @__PURE__ */ React6.createElement(Text, { style: styles2.formStorageType }, strings.storageTypeLabel(storageName)), /* @__PURE__ */ React6.createElement(Text, { style: styles2.formLabel }, strings.keyLabel), /* @__PURE__ */ React6.createElement(
|
|
834
|
-
TextInput,
|
|
835
|
-
{
|
|
836
|
-
style: [styles2.formInput, isEdit && styles2.formInputDisabled],
|
|
837
|
-
value: key,
|
|
838
|
-
onChangeText: setKey,
|
|
839
|
-
placeholder: strings.enterKeyPlaceholder,
|
|
840
|
-
placeholderTextColor: theme.colors.textMuted,
|
|
841
|
-
editable: !isEdit,
|
|
842
|
-
autoCapitalize: "none",
|
|
843
|
-
multiline: true
|
|
844
|
-
}
|
|
845
|
-
), /* @__PURE__ */ React6.createElement(Text, { style: styles2.formLabel }, strings.valueLabel), /* @__PURE__ */ React6.createElement(
|
|
846
|
-
TextInput,
|
|
685
|
+
borderWidth: 1,
|
|
686
|
+
borderColor: colors2.text
|
|
687
|
+
},
|
|
688
|
+
confirmButtonDanger: {
|
|
689
|
+
backgroundColor: colors2.text
|
|
690
|
+
},
|
|
691
|
+
formButtonSubmit: {
|
|
692
|
+
backgroundColor: colors2.text
|
|
693
|
+
},
|
|
694
|
+
confirmButtonText: {
|
|
695
|
+
fontSize: 16,
|
|
696
|
+
fontWeight: "600"
|
|
697
|
+
},
|
|
698
|
+
confirmButtonTextSecondary: {
|
|
699
|
+
color: colors2.text
|
|
700
|
+
},
|
|
701
|
+
confirmButtonTextDanger: {
|
|
702
|
+
color: colors2.inverted
|
|
703
|
+
},
|
|
704
|
+
formButtonTextSubmit: {
|
|
705
|
+
color: colors2.inverted
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
function ItemRowActions(props) {
|
|
709
|
+
const {
|
|
710
|
+
item,
|
|
711
|
+
onCopy,
|
|
712
|
+
onEdit,
|
|
713
|
+
onDelete,
|
|
714
|
+
showChevron = false,
|
|
715
|
+
chevronDirection = "down"
|
|
716
|
+
} = props;
|
|
717
|
+
return /* @__PURE__ */ React7.createElement(View, { style: styles5.itemRowActions }, /* @__PURE__ */ React7.createElement(IconButton, { name: "copy", onPress: () => onCopy(item) }), /* @__PURE__ */ React7.createElement(IconButton, { name: "edit", onPress: () => onEdit(item) }), /* @__PURE__ */ React7.createElement(IconButton, { name: "trash", onPress: () => onDelete(item) }), showChevron && /* @__PURE__ */ React7.createElement(View, { style: styles5.iconSlot }, /* @__PURE__ */ React7.createElement(
|
|
718
|
+
Icon,
|
|
847
719
|
{
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
placeholder: strings.enterValuePlaceholder,
|
|
852
|
-
placeholderTextColor: theme.colors.textMuted,
|
|
853
|
-
multiline: true,
|
|
854
|
-
numberOfLines: 3
|
|
720
|
+
name: chevronDirection === "up" ? "chevronUp" : "chevronDown",
|
|
721
|
+
size: LAYOUT.chevronSize,
|
|
722
|
+
tintColor: theme.colors.text
|
|
855
723
|
}
|
|
856
|
-
)
|
|
857
|
-
TouchableOpacity,
|
|
858
|
-
{
|
|
859
|
-
style: [styles2.formButton, styles2.formButtonCancel],
|
|
860
|
-
onPress: onCancel,
|
|
861
|
-
disabled: saving
|
|
862
|
-
},
|
|
863
|
-
/* @__PURE__ */ React6.createElement(Text, { style: [styles2.formButtonText, styles2.formButtonTextCancel] }, strings.cancel)
|
|
864
|
-
), /* @__PURE__ */ React6.createElement(
|
|
865
|
-
TouchableOpacity,
|
|
866
|
-
{
|
|
867
|
-
style: [styles2.formButton, styles2.formButtonSubmit],
|
|
868
|
-
onPress: handleSubmit,
|
|
869
|
-
disabled: saving
|
|
870
|
-
},
|
|
871
|
-
/* @__PURE__ */ React6.createElement(Text, { style: [styles2.formButtonText, styles2.formButtonTextSubmit] }, saving ? strings.saving : isEdit ? strings.save : strings.add)
|
|
872
|
-
)))));
|
|
724
|
+
)));
|
|
873
725
|
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
726
|
+
var styles5 = StyleSheet.create({
|
|
727
|
+
itemRowActions: {
|
|
728
|
+
flexDirection: "row",
|
|
729
|
+
alignItems: "center",
|
|
730
|
+
marginLeft: LAYOUT.iconGap,
|
|
731
|
+
gap: LAYOUT.iconGap
|
|
732
|
+
},
|
|
733
|
+
iconSlot: {
|
|
734
|
+
width: LAYOUT.iconButtonSize,
|
|
735
|
+
height: LAYOUT.iconButtonSize,
|
|
736
|
+
alignItems: "center",
|
|
737
|
+
justifyContent: "center"
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
// src/components/StorageList.tsx
|
|
742
|
+
function StorageList(props) {
|
|
743
|
+
const { item, onCopy, onEdit, onDelete } = props;
|
|
744
|
+
const [expandedKeys, setExpandedKeys] = useState(/* @__PURE__ */ new Set());
|
|
745
|
+
const charCount = item.value.length;
|
|
746
|
+
const handleToggleExpanded = () => {
|
|
747
|
+
setExpandedKeys((prev) => {
|
|
748
|
+
const next = new Set(prev);
|
|
749
|
+
if (next.has(item.key)) next.delete(item.key);
|
|
750
|
+
else next.add(item.key);
|
|
751
|
+
return next;
|
|
752
|
+
});
|
|
886
753
|
};
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
style: { flex: 1, width: "100%" },
|
|
891
|
-
activeOpacity: 1,
|
|
892
|
-
onPress: onCancel
|
|
893
|
-
}
|
|
894
|
-
), /* @__PURE__ */ React6.createElement(View, { style: styles2.confirmModal }, /* @__PURE__ */ React6.createElement(View, { style: styles2.confirmHeader }, /* @__PURE__ */ React6.createElement(Text, { style: styles2.confirmTitle }, title), /* @__PURE__ */ React6.createElement(
|
|
895
|
-
IconButton,
|
|
754
|
+
const isExpanded = expandedKeys.has(item.key);
|
|
755
|
+
return /* @__PURE__ */ React7.createElement(View, { style: styles6.itemRow }, /* @__PURE__ */ React7.createElement(TouchableOpacity, { onPress: handleToggleExpanded, activeOpacity: 0.7 }, /* @__PURE__ */ React7.createElement(View, { style: styles6.itemRowCollapsed }, /* @__PURE__ */ React7.createElement(View, { style: { flex: 1 } }, /* @__PURE__ */ React7.createElement(Text, { style: styles6.itemKey, numberOfLines: 1 }, item.key), /* @__PURE__ */ React7.createElement(Text, { style: styles6.itemChars }, strings.charCount(charCount))), !isExpanded ? /* @__PURE__ */ React7.createElement(
|
|
756
|
+
ItemRowActions,
|
|
896
757
|
{
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
758
|
+
item,
|
|
759
|
+
onCopy,
|
|
760
|
+
onEdit,
|
|
761
|
+
onDelete,
|
|
762
|
+
showChevron: true,
|
|
763
|
+
chevronDirection: "down"
|
|
903
764
|
}
|
|
904
|
-
)
|
|
905
|
-
TouchableOpacity,
|
|
906
|
-
{
|
|
907
|
-
style: [styles2.confirmButton, styles2.confirmButtonSecondary],
|
|
908
|
-
onPress: onCancel
|
|
909
|
-
},
|
|
910
|
-
/* @__PURE__ */ React6.createElement(Text, { style: [styles2.confirmButtonText, styles2.confirmButtonTextSecondary] }, cancelLabel)
|
|
911
|
-
), /* @__PURE__ */ React6.createElement(
|
|
912
|
-
TouchableOpacity,
|
|
913
|
-
{
|
|
914
|
-
style: [
|
|
915
|
-
styles2.confirmButton,
|
|
916
|
-
danger ? styles2.confirmButtonDanger : styles2.formButtonSubmit
|
|
917
|
-
],
|
|
918
|
-
onPress: handleConfirm
|
|
919
|
-
},
|
|
920
|
-
/* @__PURE__ */ React6.createElement(
|
|
921
|
-
Text,
|
|
922
|
-
{
|
|
923
|
-
style: [
|
|
924
|
-
styles2.confirmButtonText,
|
|
925
|
-
danger ? styles2.confirmButtonTextDanger : styles2.formButtonTextSubmit
|
|
926
|
-
]
|
|
927
|
-
},
|
|
928
|
-
confirmLabel
|
|
929
|
-
)
|
|
930
|
-
)))));
|
|
931
|
-
}
|
|
932
|
-
function ItemRowActions({
|
|
933
|
-
item,
|
|
934
|
-
onCopy,
|
|
935
|
-
onEdit,
|
|
936
|
-
onDelete,
|
|
937
|
-
showChevron = false,
|
|
938
|
-
chevronDirection = "down"
|
|
939
|
-
}) {
|
|
940
|
-
return /* @__PURE__ */ React6.createElement(View, { style: styles2.itemRowActions }, /* @__PURE__ */ React6.createElement(IconButton, { name: "copy", onPress: () => onCopy(item) }), /* @__PURE__ */ React6.createElement(IconButton, { name: "edit", onPress: () => onEdit(item) }), /* @__PURE__ */ React6.createElement(IconButton, { name: "trash", onPress: () => onDelete(item) }), showChevron && /* @__PURE__ */ React6.createElement(View, { style: styles2.iconSlot }, /* @__PURE__ */ React6.createElement(
|
|
765
|
+
) : /* @__PURE__ */ React7.createElement(View, { style: styles6.iconSlot }, /* @__PURE__ */ React7.createElement(
|
|
941
766
|
Icon,
|
|
942
767
|
{
|
|
943
|
-
name:
|
|
768
|
+
name: "chevronUp",
|
|
944
769
|
size: LAYOUT.chevronSize,
|
|
945
770
|
tintColor: theme.colors.text
|
|
946
771
|
}
|
|
772
|
+
)))), isExpanded && /* @__PURE__ */ React7.createElement(View, { style: styles6.itemRowExpanded }, /* @__PURE__ */ React7.createElement(TouchableOpacity, { onPress: () => onEdit(item), style: styles6.valueBox }, /* @__PURE__ */ React7.createElement(Text, { style: styles6.valueBoxLabel }, strings.valueLabel), /* @__PURE__ */ React7.createElement(Text, { style: styles6.valueBoxText, selectable: true }, item.value)), /* @__PURE__ */ React7.createElement(
|
|
773
|
+
ItemRowActions,
|
|
774
|
+
{
|
|
775
|
+
item,
|
|
776
|
+
onCopy,
|
|
777
|
+
onEdit,
|
|
778
|
+
onDelete
|
|
779
|
+
}
|
|
947
780
|
)));
|
|
948
781
|
}
|
|
782
|
+
var { colors: colors3 } = theme;
|
|
783
|
+
var styles6 = StyleSheet.create({
|
|
784
|
+
itemRow: {
|
|
785
|
+
minHeight: LAYOUT.rowMinHeight,
|
|
786
|
+
paddingHorizontal: LAYOUT.padding,
|
|
787
|
+
paddingVertical: 12,
|
|
788
|
+
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
789
|
+
borderBottomColor: colors3.borderLight,
|
|
790
|
+
backgroundColor: colors3.background,
|
|
791
|
+
marginHorizontal: LAYOUT.padding,
|
|
792
|
+
marginBottom: 4
|
|
793
|
+
},
|
|
794
|
+
itemRowCollapsed: {
|
|
795
|
+
flexDirection: "row",
|
|
796
|
+
alignItems: "center",
|
|
797
|
+
alignSelf: "stretch"
|
|
798
|
+
},
|
|
799
|
+
itemKey: {
|
|
800
|
+
flex: 1,
|
|
801
|
+
fontSize: LAYOUT.fontSize,
|
|
802
|
+
fontWeight: "500",
|
|
803
|
+
color: colors3.text
|
|
804
|
+
},
|
|
805
|
+
itemChars: {
|
|
806
|
+
fontSize: 12,
|
|
807
|
+
color: colors3.textSecondary,
|
|
808
|
+
marginTop: 2
|
|
809
|
+
},
|
|
810
|
+
iconSlot: {
|
|
811
|
+
width: LAYOUT.iconButtonSize,
|
|
812
|
+
height: LAYOUT.iconButtonSize,
|
|
813
|
+
alignItems: "center",
|
|
814
|
+
justifyContent: "center"
|
|
815
|
+
},
|
|
816
|
+
itemRowExpanded: {
|
|
817
|
+
paddingTop: 4
|
|
818
|
+
},
|
|
819
|
+
valueBox: {
|
|
820
|
+
backgroundColor: colors3.backgroundSecondary,
|
|
821
|
+
borderRadius: 8,
|
|
822
|
+
padding: 12,
|
|
823
|
+
marginTop: 8,
|
|
824
|
+
marginBottom: 8,
|
|
825
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
826
|
+
borderColor: colors3.border
|
|
827
|
+
},
|
|
828
|
+
valueBoxLabel: {
|
|
829
|
+
fontSize: 11,
|
|
830
|
+
fontWeight: "600",
|
|
831
|
+
color: colors3.textSecondary,
|
|
832
|
+
marginBottom: 4,
|
|
833
|
+
textTransform: "uppercase"
|
|
834
|
+
},
|
|
835
|
+
valueBoxText: {
|
|
836
|
+
fontSize: LAYOUT.fontSize,
|
|
837
|
+
color: colors3.text
|
|
838
|
+
}
|
|
839
|
+
});
|
|
949
840
|
|
|
950
841
|
// src/components/StorageSection.tsx
|
|
951
|
-
function StorageSection({
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
refreshTrigger
|
|
960
|
-
}) {
|
|
842
|
+
function StorageSection(props) {
|
|
843
|
+
const {
|
|
844
|
+
adapter,
|
|
845
|
+
defaultExpanded = true,
|
|
846
|
+
expanded: expandedProp,
|
|
847
|
+
onToggleExpanded,
|
|
848
|
+
refreshTrigger
|
|
849
|
+
} = props;
|
|
961
850
|
const { items, loading, error, refresh } = useStorageItems(adapter);
|
|
962
851
|
const [expandedInternal, setExpandedInternal] = useState(defaultExpanded);
|
|
963
852
|
const expanded = expandedProp !== void 0 ? expandedProp : expandedInternal;
|
|
@@ -968,7 +857,6 @@ function StorageSection({
|
|
|
968
857
|
useEffect(() => {
|
|
969
858
|
if (refreshTrigger !== void 0) refresh();
|
|
970
859
|
}, [refreshTrigger, refresh]);
|
|
971
|
-
const [expandedKeys, setExpandedKeys] = useState(/* @__PURE__ */ new Set());
|
|
972
860
|
const [formVisible, setFormVisible] = useState(false);
|
|
973
861
|
const [editingItem, setEditingItem] = useState(null);
|
|
974
862
|
const [deleteItem, setDeleteItem] = useState(null);
|
|
@@ -982,14 +870,7 @@ function StorageSection({
|
|
|
982
870
|
setFormVisible(true);
|
|
983
871
|
};
|
|
984
872
|
const handleSave = async (key, value) => {
|
|
985
|
-
const isNewKey = !editingItem || editingItem.key !== key;
|
|
986
873
|
await adapter.setItem(key, value);
|
|
987
|
-
if (adapter.type === "keychain" && isNewKey) {
|
|
988
|
-
onKeychainKeyAdded?.(key);
|
|
989
|
-
}
|
|
990
|
-
if (adapter.type === "expo-secure-store" && isNewKey) {
|
|
991
|
-
onSecureStoreKeyAdded?.(key);
|
|
992
|
-
}
|
|
993
874
|
await refresh();
|
|
994
875
|
};
|
|
995
876
|
const handleDeleteItem = async () => {
|
|
@@ -1017,25 +898,25 @@ function StorageSection({
|
|
|
1017
898
|
};
|
|
1018
899
|
const isKeychain = adapter.type === "keychain";
|
|
1019
900
|
const isSecureStore = adapter.type === "expo-secure-store";
|
|
1020
|
-
const showKeychainHint = isKeychain && items.length === 0
|
|
901
|
+
const showKeychainHint = isKeychain && items.length === 0;
|
|
1021
902
|
const showSecureStoreHint = isSecureStore && items.length === 0;
|
|
1022
903
|
if (!adapter.isAvailable()) return null;
|
|
1023
|
-
return /* @__PURE__ */
|
|
904
|
+
return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(
|
|
1024
905
|
TouchableOpacity,
|
|
1025
906
|
{
|
|
1026
|
-
style:
|
|
907
|
+
style: styles7.sectionHeader,
|
|
1027
908
|
onPress: handleToggleExpanded,
|
|
1028
909
|
activeOpacity: 0.7
|
|
1029
910
|
},
|
|
1030
|
-
/* @__PURE__ */
|
|
1031
|
-
/* @__PURE__ */
|
|
911
|
+
/* @__PURE__ */ React7.createElement(View, { style: styles7.sectionHeaderLabelWrap }, /* @__PURE__ */ React7.createElement(Text, { style: styles7.sectionHeaderLabel }, adapter.name, /* @__PURE__ */ React7.createElement(Text, { style: styles7.sectionHeaderCount }, " (", items.length, ")"))),
|
|
912
|
+
/* @__PURE__ */ React7.createElement(View, { style: styles7.storageRowActions }, /* @__PURE__ */ React7.createElement(IconButton, { name: "plus", onPress: handleAdd }), /* @__PURE__ */ React7.createElement(
|
|
1032
913
|
IconButton,
|
|
1033
914
|
{
|
|
1034
915
|
name: "trash",
|
|
1035
916
|
onPress: () => items.length > 0 && setClearAllVisible(true),
|
|
1036
917
|
disabled: items.length === 0
|
|
1037
918
|
}
|
|
1038
|
-
), /* @__PURE__ */
|
|
919
|
+
), /* @__PURE__ */ React7.createElement(View, { style: styles7.iconSlot }, /* @__PURE__ */ React7.createElement(
|
|
1039
920
|
Icon,
|
|
1040
921
|
{
|
|
1041
922
|
name: expanded ? "chevronUp" : "chevronDown",
|
|
@@ -1043,60 +924,16 @@ function StorageSection({
|
|
|
1043
924
|
tintColor: theme.colors.text
|
|
1044
925
|
}
|
|
1045
926
|
)))
|
|
1046
|
-
), expanded && /* @__PURE__ */
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
};
|
|
1057
|
-
return /* @__PURE__ */ React6.createElement(View, { key: item.key, style: styles2.itemRow }, /* @__PURE__ */ React6.createElement(
|
|
1058
|
-
TouchableOpacity,
|
|
1059
|
-
{
|
|
1060
|
-
key: item.key,
|
|
1061
|
-
onPress: toggleItemExpanded,
|
|
1062
|
-
activeOpacity: 0.7
|
|
1063
|
-
},
|
|
1064
|
-
/* @__PURE__ */ React6.createElement(View, { style: styles2.itemRowCollapsed }, /* @__PURE__ */ React6.createElement(View, { style: { flex: 1 } }, /* @__PURE__ */ React6.createElement(Text, { style: styles2.itemKey, numberOfLines: 1 }, item.key), /* @__PURE__ */ React6.createElement(Text, { style: styles2.itemChars }, strings.charCount(charCount))), !isItemExpanded ? /* @__PURE__ */ React6.createElement(
|
|
1065
|
-
ItemRowActions,
|
|
1066
|
-
{
|
|
1067
|
-
item,
|
|
1068
|
-
onCopy: handleCopy,
|
|
1069
|
-
onEdit: handleEdit,
|
|
1070
|
-
onDelete: setDeleteItem,
|
|
1071
|
-
showChevron: true,
|
|
1072
|
-
chevronDirection: "down"
|
|
1073
|
-
}
|
|
1074
|
-
) : /* @__PURE__ */ React6.createElement(View, { style: styles2.iconSlot }, /* @__PURE__ */ React6.createElement(
|
|
1075
|
-
Icon,
|
|
1076
|
-
{
|
|
1077
|
-
name: "chevronUp",
|
|
1078
|
-
size: LAYOUT.chevronSize,
|
|
1079
|
-
tintColor: theme.colors.text
|
|
1080
|
-
}
|
|
1081
|
-
)))
|
|
1082
|
-
), isItemExpanded && /* @__PURE__ */ React6.createElement(View, { style: styles2.itemRowExpanded }, /* @__PURE__ */ React6.createElement(
|
|
1083
|
-
TouchableOpacity,
|
|
1084
|
-
{
|
|
1085
|
-
onPress: () => handleEdit(item),
|
|
1086
|
-
style: styles2.valueBox
|
|
1087
|
-
},
|
|
1088
|
-
/* @__PURE__ */ React6.createElement(Text, { style: styles2.valueBoxLabel }, strings.valueLabel),
|
|
1089
|
-
/* @__PURE__ */ React6.createElement(Text, { style: styles2.valueBoxText, selectable: true }, item.value || strings.emptyValue)
|
|
1090
|
-
), /* @__PURE__ */ React6.createElement(
|
|
1091
|
-
ItemRowActions,
|
|
1092
|
-
{
|
|
1093
|
-
item,
|
|
1094
|
-
onCopy: handleCopy,
|
|
1095
|
-
onEdit: handleEdit,
|
|
1096
|
-
onDelete: setDeleteItem
|
|
1097
|
-
}
|
|
1098
|
-
)));
|
|
1099
|
-
}), !loading && items.length === 0 && !showKeychainHint && !showSecureStoreHint ? /* @__PURE__ */ React6.createElement(View, { style: styles2.empty }, /* @__PURE__ */ React6.createElement(Text, { style: styles2.emptyText }, strings.noItems)) : null), /* @__PURE__ */ React6.createElement(
|
|
927
|
+
), expanded && /* @__PURE__ */ React7.createElement(React7.Fragment, null, showKeychainHint ? /* @__PURE__ */ React7.createElement(View, { style: styles7.keychainHint }, /* @__PURE__ */ React7.createElement(Text, { style: styles7.keychainHintText }, strings.keychainHint)) : null, showSecureStoreHint ? /* @__PURE__ */ React7.createElement(View, { style: styles7.keychainHint }, /* @__PURE__ */ React7.createElement(Text, { style: styles7.keychainHintText }, strings.secureStoreHint)) : null, error ? /* @__PURE__ */ React7.createElement(View, { style: styles7.error }, /* @__PURE__ */ React7.createElement(Text, { style: styles7.errorText }, error)) : null, loading ? /* @__PURE__ */ React7.createElement(View, { style: styles7.loading }, /* @__PURE__ */ React7.createElement(Text, { style: styles7.loadingText }, strings.loading)) : items.map((item) => /* @__PURE__ */ React7.createElement(
|
|
928
|
+
StorageList,
|
|
929
|
+
{
|
|
930
|
+
key: item.key,
|
|
931
|
+
item,
|
|
932
|
+
onCopy: handleCopy,
|
|
933
|
+
onEdit: handleEdit,
|
|
934
|
+
onDelete: setDeleteItem
|
|
935
|
+
}
|
|
936
|
+
)), !loading && items.length === 0 && !showKeychainHint && !showSecureStoreHint ? /* @__PURE__ */ React7.createElement(View, { style: styles7.empty }, /* @__PURE__ */ React7.createElement(Text, { style: styles7.emptyText }, strings.noItems)) : null), /* @__PURE__ */ React7.createElement(
|
|
1100
937
|
ItemForm,
|
|
1101
938
|
{
|
|
1102
939
|
visible: formVisible,
|
|
@@ -1108,7 +945,7 @@ function StorageSection({
|
|
|
1108
945
|
setEditingItem(null);
|
|
1109
946
|
}
|
|
1110
947
|
}
|
|
1111
|
-
), /* @__PURE__ */
|
|
948
|
+
), /* @__PURE__ */ React7.createElement(
|
|
1112
949
|
ConfirmModal,
|
|
1113
950
|
{
|
|
1114
951
|
visible: deleteItem !== null,
|
|
@@ -1117,7 +954,7 @@ function StorageSection({
|
|
|
1117
954
|
onConfirm: handleDeleteItem,
|
|
1118
955
|
onCancel: () => setDeleteItem(null)
|
|
1119
956
|
}
|
|
1120
|
-
), /* @__PURE__ */
|
|
957
|
+
), /* @__PURE__ */ React7.createElement(
|
|
1121
958
|
ConfirmModal,
|
|
1122
959
|
{
|
|
1123
960
|
visible: clearAllVisible,
|
|
@@ -1128,30 +965,92 @@ function StorageSection({
|
|
|
1128
965
|
}
|
|
1129
966
|
));
|
|
1130
967
|
}
|
|
968
|
+
var { colors: colors4 } = theme;
|
|
969
|
+
var styles7 = StyleSheet.create({
|
|
970
|
+
sectionHeader: {
|
|
971
|
+
height: LAYOUT.sectionHeaderHeight,
|
|
972
|
+
flexDirection: "row",
|
|
973
|
+
alignItems: "center",
|
|
974
|
+
paddingHorizontal: LAYOUT.padding,
|
|
975
|
+
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
976
|
+
borderBottomColor: colors4.border,
|
|
977
|
+
backgroundColor: colors4.backgroundSecondary,
|
|
978
|
+
marginTop: LAYOUT.padding,
|
|
979
|
+
marginHorizontal: LAYOUT.padding,
|
|
980
|
+
borderRadius: LAYOUT.sectionRadius
|
|
981
|
+
},
|
|
982
|
+
sectionHeaderLabelWrap: {
|
|
983
|
+
flex: 1
|
|
984
|
+
},
|
|
985
|
+
sectionHeaderLabel: {
|
|
986
|
+
fontSize: 15,
|
|
987
|
+
fontWeight: "600",
|
|
988
|
+
color: colors4.text
|
|
989
|
+
},
|
|
990
|
+
sectionHeaderCount: {
|
|
991
|
+
color: colors4.textSecondary,
|
|
992
|
+
fontWeight: "400"
|
|
993
|
+
},
|
|
994
|
+
storageRowActions: {
|
|
995
|
+
flexDirection: "row",
|
|
996
|
+
alignItems: "center",
|
|
997
|
+
gap: LAYOUT.iconGap
|
|
998
|
+
},
|
|
999
|
+
iconSlot: {
|
|
1000
|
+
width: LAYOUT.iconButtonSize,
|
|
1001
|
+
height: LAYOUT.iconButtonSize,
|
|
1002
|
+
alignItems: "center",
|
|
1003
|
+
justifyContent: "center"
|
|
1004
|
+
},
|
|
1005
|
+
keychainHint: {
|
|
1006
|
+
padding: LAYOUT.padding,
|
|
1007
|
+
marginHorizontal: LAYOUT.padding,
|
|
1008
|
+
marginTop: 8,
|
|
1009
|
+
marginBottom: 4,
|
|
1010
|
+
backgroundColor: colors4.backgroundSecondary,
|
|
1011
|
+
borderRadius: 8
|
|
1012
|
+
},
|
|
1013
|
+
keychainHintText: {
|
|
1014
|
+
fontSize: LAYOUT.fontSize - 1,
|
|
1015
|
+
color: colors4.textSecondary
|
|
1016
|
+
},
|
|
1017
|
+
error: {
|
|
1018
|
+
padding: LAYOUT.padding,
|
|
1019
|
+
backgroundColor: colors4.backgroundTertiary,
|
|
1020
|
+
marginHorizontal: LAYOUT.padding,
|
|
1021
|
+
marginVertical: 8,
|
|
1022
|
+
borderRadius: 8
|
|
1023
|
+
},
|
|
1024
|
+
errorText: {
|
|
1025
|
+
fontSize: LAYOUT.fontSize,
|
|
1026
|
+
color: colors4.text
|
|
1027
|
+
},
|
|
1028
|
+
loading: {
|
|
1029
|
+
padding: LAYOUT.padding * 2,
|
|
1030
|
+
alignItems: "center",
|
|
1031
|
+
marginHorizontal: LAYOUT.padding
|
|
1032
|
+
},
|
|
1033
|
+
loadingText: {
|
|
1034
|
+
fontSize: LAYOUT.fontSize,
|
|
1035
|
+
color: colors4.textSecondary
|
|
1036
|
+
},
|
|
1037
|
+
empty: {
|
|
1038
|
+
padding: LAYOUT.padding * 2,
|
|
1039
|
+
alignItems: "center",
|
|
1040
|
+
marginHorizontal: LAYOUT.padding
|
|
1041
|
+
},
|
|
1042
|
+
emptyText: {
|
|
1043
|
+
fontSize: LAYOUT.fontSize,
|
|
1044
|
+
color: colors4.textMuted
|
|
1045
|
+
}
|
|
1046
|
+
});
|
|
1131
1047
|
|
|
1132
1048
|
// src/components/StorageInspector.tsx
|
|
1133
|
-
function StorageInspector({
|
|
1134
|
-
mmkvInstances = [],
|
|
1135
|
-
asyncStorageInstance,
|
|
1136
|
-
keychainKeys: keychainKeysProp,
|
|
1137
|
-
keychainInstance,
|
|
1138
|
-
secureStoreKeys: secureStoreKeysProp,
|
|
1139
|
-
secureStoreInstance,
|
|
1140
|
-
customAdapters = []
|
|
1141
|
-
}) {
|
|
1142
|
-
const [keychainKeysAdded, setKeychainKeysAdded] = useState([]);
|
|
1143
|
-
const [secureStoreKeysAdded, setSecureStoreKeysAdded] = useState([]);
|
|
1049
|
+
function StorageInspector(props) {
|
|
1050
|
+
const { mmkvInstances = [], secureStoreKeys, customAdapters = [] } = props;
|
|
1144
1051
|
const [refreshKey, setRefreshKey] = useState(0);
|
|
1145
1052
|
const [refreshing, setRefreshing] = useState(false);
|
|
1146
1053
|
const [expandedIndices, setExpandedIndices] = useState(() => /* @__PURE__ */ new Set([0]));
|
|
1147
|
-
const keychainKeys = useMemo(
|
|
1148
|
-
() => [...keychainKeysProp ?? [], ...keychainKeysAdded],
|
|
1149
|
-
[keychainKeysProp, keychainKeysAdded]
|
|
1150
|
-
);
|
|
1151
|
-
const secureStoreKeys = useMemo(
|
|
1152
|
-
() => [...secureStoreKeysProp ?? [], ...secureStoreKeysAdded],
|
|
1153
|
-
[secureStoreKeysProp, secureStoreKeysAdded]
|
|
1154
|
-
);
|
|
1155
1054
|
const adapters = useMemo(() => {
|
|
1156
1055
|
const list = [];
|
|
1157
1056
|
mmkvInstances.forEach((inst, i) => {
|
|
@@ -1159,58 +1058,34 @@ function StorageInspector({
|
|
|
1159
1058
|
createMMKVAdapter(inst, mmkvInstances.length > 1 ? `MMKV ${i + 1}` : "MMKV")
|
|
1160
1059
|
);
|
|
1161
1060
|
});
|
|
1162
|
-
const asyncAdapter = createAsyncStorageAdapter(
|
|
1061
|
+
const asyncAdapter = createAsyncStorageAdapter();
|
|
1163
1062
|
if (asyncAdapter.isAvailable()) list.push(asyncAdapter);
|
|
1164
|
-
const keychainAdapter = createKeychainAdapter(
|
|
1063
|
+
const keychainAdapter = createKeychainAdapter();
|
|
1165
1064
|
if (keychainAdapter.isAvailable()) list.push(keychainAdapter);
|
|
1166
|
-
const secureStoreAdapter = createSecureStoreAdapter(
|
|
1167
|
-
secureStoreKeys,
|
|
1168
|
-
secureStoreInstance
|
|
1169
|
-
);
|
|
1065
|
+
const secureStoreAdapter = createSecureStoreAdapter(secureStoreKeys ?? []);
|
|
1170
1066
|
if (secureStoreAdapter.isAvailable()) list.push(secureStoreAdapter);
|
|
1171
1067
|
list.push(...customAdapters);
|
|
1172
1068
|
return list;
|
|
1173
|
-
}, [
|
|
1174
|
-
mmkvInstances,
|
|
1175
|
-
asyncStorageInstance,
|
|
1176
|
-
keychainKeys,
|
|
1177
|
-
keychainInstance,
|
|
1178
|
-
secureStoreKeys,
|
|
1179
|
-
secureStoreInstance,
|
|
1180
|
-
customAdapters
|
|
1181
|
-
]);
|
|
1182
|
-
const handleKeychainKeyAdded = (key) => {
|
|
1183
|
-
setKeychainKeysAdded(
|
|
1184
|
-
(prev) => prev.includes(key) ? prev : [...prev, key]
|
|
1185
|
-
);
|
|
1186
|
-
};
|
|
1187
|
-
const handleSecureStoreKeyAdded = (key) => {
|
|
1188
|
-
setSecureStoreKeysAdded(
|
|
1189
|
-
(prev) => prev.includes(key) ? prev : [...prev, key]
|
|
1190
|
-
);
|
|
1191
|
-
};
|
|
1069
|
+
}, [mmkvInstances, secureStoreKeys, customAdapters]);
|
|
1192
1070
|
const handleRefresh = () => {
|
|
1193
1071
|
setRefreshing(true);
|
|
1194
1072
|
setRefreshKey((k) => k + 1);
|
|
1195
1073
|
setTimeout(() => setRefreshing(false), 400);
|
|
1196
1074
|
};
|
|
1197
|
-
return /* @__PURE__ */
|
|
1075
|
+
return /* @__PURE__ */ React7.createElement(View, { style: styles8.container }, /* @__PURE__ */ React7.createElement(View, { style: styles8.content }, adapters.length > 0 ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(
|
|
1198
1076
|
ScrollView,
|
|
1199
1077
|
{
|
|
1200
|
-
style:
|
|
1201
|
-
contentContainerStyle:
|
|
1078
|
+
style: styles8.scroll,
|
|
1079
|
+
contentContainerStyle: styles8.scrollContent,
|
|
1202
1080
|
keyboardShouldPersistTaps: "handled",
|
|
1203
1081
|
showsVerticalScrollIndicator: true,
|
|
1204
|
-
refreshControl: /* @__PURE__ */
|
|
1082
|
+
refreshControl: /* @__PURE__ */ React7.createElement(RefreshControl, { refreshing, onRefresh: handleRefresh })
|
|
1205
1083
|
},
|
|
1206
|
-
adapters.map((adapter, index) => /* @__PURE__ */
|
|
1084
|
+
adapters.map((adapter, index) => /* @__PURE__ */ React7.createElement(
|
|
1207
1085
|
StorageSection,
|
|
1208
1086
|
{
|
|
1209
1087
|
key: `${adapter.type}-${index}`,
|
|
1210
1088
|
adapter,
|
|
1211
|
-
keychainKeys: keychainKeysProp,
|
|
1212
|
-
onKeychainKeyAdded: handleKeychainKeyAdded,
|
|
1213
|
-
onSecureStoreKeyAdded: handleSecureStoreKeyAdded,
|
|
1214
1089
|
expanded: expandedIndices.has(index),
|
|
1215
1090
|
onToggleExpanded: () => {
|
|
1216
1091
|
setExpandedIndices((prev) => {
|
|
@@ -1223,18 +1098,57 @@ function StorageInspector({
|
|
|
1223
1098
|
refreshTrigger: refreshKey
|
|
1224
1099
|
}
|
|
1225
1100
|
))
|
|
1226
|
-
), /* @__PURE__ */
|
|
1101
|
+
), /* @__PURE__ */ React7.createElement(
|
|
1227
1102
|
IconButton,
|
|
1228
1103
|
{
|
|
1229
1104
|
name: "refresh",
|
|
1230
1105
|
onPress: handleRefresh,
|
|
1231
1106
|
size: 24,
|
|
1232
1107
|
tintColor: theme.colors.inverted,
|
|
1233
|
-
style:
|
|
1108
|
+
style: styles8.fab,
|
|
1234
1109
|
activeOpacity: 0.85
|
|
1235
1110
|
}
|
|
1236
|
-
)) : /* @__PURE__ */
|
|
1111
|
+
)) : /* @__PURE__ */ React7.createElement(View, { style: styles8.empty }, /* @__PURE__ */ React7.createElement(Text, { style: styles8.emptyText }, strings.noAdapterAvailable))));
|
|
1237
1112
|
}
|
|
1113
|
+
var { colors: colors5 } = theme;
|
|
1114
|
+
var styles8 = StyleSheet.create({
|
|
1115
|
+
container: {
|
|
1116
|
+
flex: 1,
|
|
1117
|
+
width: "100%",
|
|
1118
|
+
backgroundColor: colors5.background
|
|
1119
|
+
},
|
|
1120
|
+
content: {
|
|
1121
|
+
flex: 1
|
|
1122
|
+
},
|
|
1123
|
+
scroll: {
|
|
1124
|
+
flex: 1
|
|
1125
|
+
},
|
|
1126
|
+
scrollContent: {
|
|
1127
|
+
flexGrow: 1,
|
|
1128
|
+
paddingBottom: LAYOUT.fabSize + LAYOUT.padding + 20,
|
|
1129
|
+
paddingTop: LAYOUT.padding
|
|
1130
|
+
},
|
|
1131
|
+
fab: {
|
|
1132
|
+
position: "absolute",
|
|
1133
|
+
bottom: LAYOUT.padding + 16,
|
|
1134
|
+
right: LAYOUT.padding + 16,
|
|
1135
|
+
width: LAYOUT.fabSize,
|
|
1136
|
+
height: LAYOUT.fabSize,
|
|
1137
|
+
borderRadius: LAYOUT.fabSize / 2,
|
|
1138
|
+
backgroundColor: colors5.text,
|
|
1139
|
+
alignItems: "center",
|
|
1140
|
+
justifyContent: "center"
|
|
1141
|
+
},
|
|
1142
|
+
empty: {
|
|
1143
|
+
padding: LAYOUT.padding * 2,
|
|
1144
|
+
alignItems: "center",
|
|
1145
|
+
marginHorizontal: LAYOUT.padding
|
|
1146
|
+
},
|
|
1147
|
+
emptyText: {
|
|
1148
|
+
fontSize: LAYOUT.fontSize,
|
|
1149
|
+
color: colors5.textMuted
|
|
1150
|
+
}
|
|
1151
|
+
});
|
|
1238
1152
|
|
|
1239
1153
|
export { StorageInspector, createAsyncStorageAdapter, createKeychainAdapter, createMMKVAdapter, createSecureStoreAdapter, strings, theme };
|
|
1240
1154
|
//# sourceMappingURL=index.mjs.map
|