add files listing
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import { createMMKV } from 'react-native-mmkv';
|
||||
import { FileDetectedEvent } from '../modules/expo-download-detect';
|
||||
|
||||
const storage = createMMKV({ id: 'vaultdrop-download-registry' });
|
||||
|
||||
const FILES_KEY = 'detected_files';
|
||||
|
||||
export type DownloadRegistryEntry = {
|
||||
id: string;
|
||||
uri: string;
|
||||
name: string;
|
||||
mimeType: string;
|
||||
size: number;
|
||||
createdAt: number;
|
||||
source: string;
|
||||
detectedAt: number;
|
||||
};
|
||||
|
||||
function getAllRaw(): DownloadRegistryEntry[] {
|
||||
const raw = storage.getString(FILES_KEY);
|
||||
if (!raw) return [];
|
||||
return JSON.parse(raw) as DownloadRegistryEntry[];
|
||||
}
|
||||
|
||||
function saveAll(entries: DownloadRegistryEntry[]) {
|
||||
storage.set(FILES_KEY, JSON.stringify(entries));
|
||||
}
|
||||
|
||||
export const downloadRegistry = {
|
||||
getAll(): DownloadRegistryEntry[] {
|
||||
return getAllRaw();
|
||||
},
|
||||
|
||||
getById(id: string): DownloadRegistryEntry | undefined {
|
||||
return getAllRaw().find((e) => e.id === id);
|
||||
},
|
||||
|
||||
add(event: FileDetectedEvent): DownloadRegistryEntry | null {
|
||||
const entries = getAllRaw();
|
||||
if (entries.some((e) => e.id === event.id)) return null;
|
||||
|
||||
const entry: DownloadRegistryEntry = {
|
||||
id: event.id,
|
||||
uri: event.uri,
|
||||
name: event.name,
|
||||
mimeType: event.mimeType,
|
||||
size: event.size,
|
||||
createdAt: event.createdAt,
|
||||
source: event.source,
|
||||
detectedAt: Date.now(),
|
||||
};
|
||||
|
||||
entries.push(entry);
|
||||
saveAll(entries);
|
||||
return entry;
|
||||
},
|
||||
|
||||
addBatch(events: FileDetectedEvent[]): DownloadRegistryEntry[] {
|
||||
const entries = getAllRaw();
|
||||
const existingIds = new Set(entries.map((e) => e.id));
|
||||
const newEntries: DownloadRegistryEntry[] = [];
|
||||
|
||||
for (const event of events) {
|
||||
if (existingIds.has(event.id)) continue;
|
||||
const entry: DownloadRegistryEntry = {
|
||||
id: event.id,
|
||||
uri: event.uri,
|
||||
name: event.name,
|
||||
mimeType: event.mimeType,
|
||||
size: event.size,
|
||||
createdAt: event.createdAt,
|
||||
source: event.source,
|
||||
detectedAt: Date.now(),
|
||||
};
|
||||
newEntries.push(entry);
|
||||
existingIds.add(event.id);
|
||||
}
|
||||
|
||||
if (newEntries.length > 0) {
|
||||
saveAll([...entries, ...newEntries]);
|
||||
}
|
||||
|
||||
return newEntries;
|
||||
},
|
||||
|
||||
remove(id: string) {
|
||||
const entries = getAllRaw().filter((e) => e.id !== id);
|
||||
saveAll(entries);
|
||||
},
|
||||
|
||||
clear() {
|
||||
storage.remove(FILES_KEY);
|
||||
},
|
||||
|
||||
count(): number {
|
||||
return getAllRaw().length;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
import { createMMKV } from 'react-native-mmkv';
|
||||
import { ONBOARDING_STEPS, CURRENT_ONBOARDING_VERSION, type OnboardingStep } from '../config/onboarding';
|
||||
import { safDirectory } from './safDirectory';
|
||||
|
||||
const storage = createMMKV({ id: 'vaultdrop-onboarding' });
|
||||
|
||||
const COMPLETED_VERSION_KEY = 'completed_version';
|
||||
const SEEN_STEPS_KEY = 'seen_steps';
|
||||
|
||||
export const onboardingStorage = {
|
||||
getCompletedVersion(): number | undefined {
|
||||
const raw = storage.getNumber(COMPLETED_VERSION_KEY);
|
||||
return raw != null ? raw : undefined;
|
||||
},
|
||||
|
||||
setCompletedVersion(version: number) {
|
||||
storage.set(COMPLETED_VERSION_KEY, version);
|
||||
},
|
||||
|
||||
getSeenSteps(): string[] {
|
||||
const raw = storage.getString(SEEN_STEPS_KEY);
|
||||
if (!raw) return [];
|
||||
return JSON.parse(raw) as string[];
|
||||
},
|
||||
|
||||
markStepSeen(stepId: string) {
|
||||
const seen = this.getSeenSteps();
|
||||
if (!seen.includes(stepId)) {
|
||||
seen.push(stepId);
|
||||
storage.set(SEEN_STEPS_KEY, JSON.stringify(seen));
|
||||
}
|
||||
},
|
||||
|
||||
getPendingSteps(): OnboardingStep[] {
|
||||
const lastVersion = this.getCompletedVersion();
|
||||
const seenIds = this.getSeenSteps();
|
||||
const folders = safDirectory.getAll();
|
||||
|
||||
return ONBOARDING_STEPS.filter((step) => {
|
||||
if (lastVersion != null && step.version <= lastVersion) return false;
|
||||
if (seenIds.includes(step.id)) return false;
|
||||
if (step.condition === 'has_no_folders' && folders.length > 0) return false;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
needsOnboarding(): boolean {
|
||||
return this.getPendingSteps().length > 0;
|
||||
},
|
||||
|
||||
reset() {
|
||||
storage.remove(COMPLETED_VERSION_KEY);
|
||||
storage.remove(SEEN_STEPS_KEY);
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
import { createMMKV } from 'react-native-mmkv';
|
||||
|
||||
export type StoredFolder = {
|
||||
id: string;
|
||||
uri: string;
|
||||
name: string;
|
||||
visible: boolean;
|
||||
};
|
||||
|
||||
const storage = createMMKV({ id: 'vaultdrop-saf' });
|
||||
|
||||
const FOLDERS_KEY = 'saf_folders';
|
||||
|
||||
function generateId(): string {
|
||||
return `folder_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
||||
}
|
||||
|
||||
function getAllRaw(): StoredFolder[] {
|
||||
const raw = storage.getString(FOLDERS_KEY);
|
||||
if (!raw) return [];
|
||||
return JSON.parse(raw) as StoredFolder[];
|
||||
}
|
||||
|
||||
function saveAll(folders: StoredFolder[]) {
|
||||
storage.set(FOLDERS_KEY, JSON.stringify(folders));
|
||||
}
|
||||
|
||||
export const safDirectory = {
|
||||
getAll(): StoredFolder[] {
|
||||
return getAllRaw();
|
||||
},
|
||||
|
||||
getVisibleFolders(): StoredFolder[] {
|
||||
return getAllRaw().filter((f) => f.visible);
|
||||
},
|
||||
|
||||
addFolder(uri: string, name: string): StoredFolder {
|
||||
const folders = getAllRaw();
|
||||
if (folders.some((f) => f.uri === uri)) {
|
||||
return folders.find((f) => f.uri === uri)!;
|
||||
}
|
||||
const folder: StoredFolder = { id: generateId(), uri, name, visible: true };
|
||||
folders.push(folder);
|
||||
saveAll(folders);
|
||||
return folder;
|
||||
},
|
||||
|
||||
removeFolder(id: string) {
|
||||
const folders = getAllRaw().filter((f) => f.id !== id);
|
||||
saveAll(folders);
|
||||
},
|
||||
|
||||
toggleVisibility(id: string) {
|
||||
const folders = getAllRaw().map((f) =>
|
||||
f.id === id ? { ...f, visible: !f.visible } : f
|
||||
);
|
||||
saveAll(folders);
|
||||
},
|
||||
|
||||
clear() {
|
||||
storage.remove(FOLDERS_KEY);
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user