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