mirror of
https://github.com/DocNR/POWR.git
synced 2025-06-05 00:32:08 +00:00
Add contact cache schema and service integration
- Add contact_cache table schema and migration - Update useContactList hook with caching support - Enhance RelayInitializer with cache initialization - Update SocialFeedService to work with caching system
This commit is contained in:
parent
b5bf32d10f
commit
f17f0c4ff4
@ -2,7 +2,7 @@
|
||||
import { SQLiteDatabase } from 'expo-sqlite';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
export const SCHEMA_VERSION = 11;
|
||||
export const SCHEMA_VERSION = 12;
|
||||
|
||||
class Schema {
|
||||
private async getCurrentVersion(db: SQLiteDatabase): Promise<number> {
|
||||
@ -145,6 +145,54 @@ class Schema {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async migrate_v12(db: SQLiteDatabase): Promise<void> {
|
||||
try {
|
||||
console.log('[Schema] Running migration v12 - Adding Contact Cache table');
|
||||
|
||||
// Create contact_cache table if it doesn't exist
|
||||
await db.execAsync(`
|
||||
CREATE TABLE IF NOT EXISTS contact_cache (
|
||||
owner_pubkey TEXT NOT NULL,
|
||||
contact_pubkey TEXT NOT NULL,
|
||||
cached_at INTEGER NOT NULL,
|
||||
PRIMARY KEY (owner_pubkey, contact_pubkey)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_contact_cache_owner
|
||||
ON contact_cache (owner_pubkey);
|
||||
`);
|
||||
|
||||
console.log('[Schema] Migration v12 completed successfully');
|
||||
} catch (error) {
|
||||
console.error('[Schema] Error in migration v12:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async addContactCacheTable(db: SQLiteDatabase): Promise<void> {
|
||||
try {
|
||||
console.log('[Schema] Running migration v12 - Adding Contact Cache table');
|
||||
|
||||
// Create contact_cache table if it doesn't exist
|
||||
await db.execAsync(`
|
||||
CREATE TABLE IF NOT EXISTS contact_cache (
|
||||
owner_pubkey TEXT NOT NULL,
|
||||
contact_pubkey TEXT NOT NULL,
|
||||
cached_at INTEGER NOT NULL,
|
||||
PRIMARY KEY (owner_pubkey, contact_pubkey)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_contact_cache_owner
|
||||
ON contact_cache (owner_pubkey);
|
||||
`);
|
||||
|
||||
console.log('[Schema] Migration v12 completed successfully');
|
||||
} catch (error) {
|
||||
console.error('[Schema] Error in migration v12:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async createTables(db: SQLiteDatabase): Promise<void> {
|
||||
try {
|
||||
@ -207,6 +255,11 @@ class Schema {
|
||||
await this.migrate_v11(db);
|
||||
}
|
||||
|
||||
if (currentVersion < 12) {
|
||||
console.log(`[Schema] Running migration from version ${currentVersion} to 12`);
|
||||
await this.migrate_v12(db);
|
||||
}
|
||||
|
||||
// Update schema version at the end of the transaction
|
||||
await this.updateSchemaVersion(db);
|
||||
});
|
||||
@ -245,6 +298,11 @@ class Schema {
|
||||
await this.migrate_v11(db);
|
||||
}
|
||||
|
||||
if (currentVersion < 12) {
|
||||
console.log(`[Schema] Running migration from version ${currentVersion} to 12`);
|
||||
await this.migrate_v12(db);
|
||||
}
|
||||
|
||||
// Update schema version
|
||||
await this.updateSchemaVersion(db);
|
||||
|
||||
|
@ -1,20 +1,64 @@
|
||||
// lib/hooks/useContactList.ts
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { NDKEvent, NDKUser, NDKKind, NDKSubscriptionCacheUsage } from '@nostr-dev-kit/ndk-mobile';
|
||||
import { useNDK } from '@/lib/hooks/useNDK';
|
||||
import { POWR_PUBKEY_HEX } from '@/lib/hooks/useFeedHooks';
|
||||
import { useDatabase } from '@/components/DatabaseProvider';
|
||||
import { getContactCacheService } from '@/lib/db/services/ContactCacheService';
|
||||
|
||||
export function useContactList(pubkey: string | undefined) {
|
||||
const { ndk } = useNDK();
|
||||
const db = useDatabase();
|
||||
const [contacts, setContacts] = useState<string[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
const [isInitialLoad, setIsInitialLoad] = useState(true);
|
||||
|
||||
// Use a ref to track if we've loaded from cache
|
||||
const loadedFromCacheRef = useRef(false);
|
||||
|
||||
// Load contacts from cache first
|
||||
useEffect(() => {
|
||||
if (!pubkey || !db || loadedFromCacheRef.current) return;
|
||||
|
||||
const loadCachedContacts = async () => {
|
||||
try {
|
||||
const contactCache = getContactCacheService(db);
|
||||
const cachedContacts = await contactCache.getCachedContacts(pubkey);
|
||||
|
||||
if (cachedContacts.length > 0) {
|
||||
console.log(`[useContactList] Loaded ${cachedContacts.length} contacts from cache`);
|
||||
|
||||
// Add self and POWR account to contacts
|
||||
const contactSet = new Set(cachedContacts);
|
||||
contactSet.add(pubkey);
|
||||
if (POWR_PUBKEY_HEX) {
|
||||
contactSet.add(POWR_PUBKEY_HEX);
|
||||
}
|
||||
|
||||
// Set contacts state with cached contacts
|
||||
setContacts(Array.from(contactSet));
|
||||
setIsInitialLoad(false);
|
||||
loadedFromCacheRef.current = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[useContactList] Error loading cached contacts:', error);
|
||||
// Don't set error state here - we'll still try to fetch from network
|
||||
}
|
||||
};
|
||||
|
||||
loadCachedContacts();
|
||||
}, [pubkey, db]);
|
||||
|
||||
// Fetch contact list from NDK
|
||||
const fetchContactList = useCallback(async () => {
|
||||
if (!ndk || !pubkey) return;
|
||||
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
if (!loadedFromCacheRef.current) {
|
||||
// Only reset error if this is not a background refresh after cache load
|
||||
setError(null);
|
||||
}
|
||||
|
||||
try {
|
||||
// Try multiple approaches to ensure reliability
|
||||
@ -92,13 +136,26 @@ export function useContactList(pubkey: string | undefined) {
|
||||
// Convert to array and update state
|
||||
const contactArray = Array.from(contactSet);
|
||||
setContacts(contactArray);
|
||||
setIsInitialLoad(false);
|
||||
|
||||
// Cache contacts if we have a database connection
|
||||
if (db && contactArray.length > 0) {
|
||||
try {
|
||||
const contactCache = getContactCacheService(db);
|
||||
await contactCache.cacheContacts(pubkey, contactArray);
|
||||
console.log(`[useContactList] Cached ${contactArray.length} contacts for ${pubkey}`);
|
||||
} catch (cacheError) {
|
||||
console.error('[useContactList] Error caching contacts:', cacheError);
|
||||
// Non-fatal, we can continue even if caching fails
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error fetching contact list:', err);
|
||||
setError(err instanceof Error ? err : new Error('Failed to fetch contacts'));
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [ndk, pubkey]);
|
||||
}, [ndk, pubkey, db]);
|
||||
|
||||
// Fetch on mount and when dependencies change
|
||||
useEffect(() => {
|
||||
@ -112,6 +169,7 @@ export function useContactList(pubkey: string | undefined) {
|
||||
isLoading,
|
||||
error,
|
||||
refetch: fetchContactList,
|
||||
hasContacts: contacts.length > 0
|
||||
hasContacts: contacts.length > 0,
|
||||
isInitialLoad
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user