POWR/components/RelayInitializer.tsx

148 lines
5.7 KiB
TypeScript
Raw Permalink Normal View History

2025-03-09 11:15:28 -04:00
// components/RelayInitializer.tsx
import React, { useEffect, useContext } from 'react';
2025-03-09 11:15:28 -04:00
import { View } from 'react-native';
import { useRelayStore } from '@/lib/stores/relayStore';
import { useNDKStore } from '@/lib/stores/ndk';
import { NDKContext } from '@/lib/auth/ReactQueryAuthProvider';
import { useConnectivity } from '@/lib/db/services/ConnectivityService';
import { ConnectivityService } from '@/lib/db/services/ConnectivityService';
import { profileImageCache } from '@/lib/db/services/ProfileImageCache';
import { bannerImageCache } from '@/lib/db/services/BannerImageCache';
import { getSocialFeedCache } from '@/lib/db/services/SocialFeedCache';
import { getContactCacheService } from '@/lib/db/services/ContactCacheService';
import { useDatabase } from '@/components/DatabaseProvider';
2025-03-09 11:15:28 -04:00
/**
* A component to initialize and load relay data when the app starts
* This should be placed high in the component tree, ideally in _layout.tsx
*/
interface RelayInitializerProps {
reactQueryMode?: boolean; // When true, uses React Query NDK context
}
export default function RelayInitializer({ reactQueryMode = false }: RelayInitializerProps) {
2025-03-09 11:15:28 -04:00
const { loadRelays } = useRelayStore();
const { isOnline } = useConnectivity();
// Get NDK from the appropriate source based on mode
const legacyNDK = useNDKStore(state => state.ndk);
const reactQueryNDKContext = useContext(NDKContext);
// Use the correct NDK instance based on mode
const ndk = reactQueryMode ? reactQueryNDKContext.ndk : legacyNDK;
2025-03-09 11:15:28 -04:00
const db = useDatabase();
// Initialize all caches with NDK instance
useEffect(() => {
if (ndk) {
console.log('[RelayInitializer] Setting NDK instance in image caches');
profileImageCache.setNDK(ndk);
bannerImageCache.setNDK(ndk);
// Cache initialization is handled within setNDK
console.log('[RelayInitializer] Image caches initialized');
// Initialize caches with NDK instance
if (db) {
// Initialize ContactCacheService
try {
getContactCacheService(db);
console.log('[RelayInitializer] ContactCacheService initialized');
} catch (error) {
console.error('[RelayInitializer] Error initializing ContactCacheService:', error);
}
// Maximum number of retry attempts
const MAX_RETRIES = 3;
const initSocialFeedCache = (attempt = 1) => {
try {
console.log(`[RelayInitializer] Attempting to initialize SocialFeedCache (attempt ${attempt}/${MAX_RETRIES})`);
const socialFeedCache = getSocialFeedCache(db);
socialFeedCache.setNDK(ndk);
console.log('[RelayInitializer] SocialFeedCache initialized with NDK successfully');
return true;
} catch (error) {
console.error('[RelayInitializer] Error initializing SocialFeedCache:', error);
// Log more detailed error information
if (error instanceof Error) {
console.error(`[RelayInitializer] Error details: ${error.message}`);
if (error.stack) {
console.error(`[RelayInitializer] Stack trace: ${error.stack}`);
}
}
return false;
}
};
// Try to initialize immediately
const success = initSocialFeedCache();
// If failed, set up progressive retries
if (!success) {
let retryAttempt = 1;
const retryTimers: NodeJS.Timeout[] = [];
// Set up multiple retries with increasing delays
const retryDelays = [2000, 5000, 10000]; // 2s, 5s, 10s
for (let i = 0; i < Math.min(MAX_RETRIES - 1, retryDelays.length); i++) {
const currentAttempt = retryAttempt + 1;
const delay = retryDelays[i];
console.log(`[RelayInitializer] Will retry SocialFeedCache initialization in ${delay/1000} seconds (attempt ${currentAttempt}/${MAX_RETRIES})`);
const timer = setTimeout(() => {
console.log(`[RelayInitializer] Retrying SocialFeedCache initialization (attempt ${currentAttempt}/${MAX_RETRIES})`);
if (initSocialFeedCache(currentAttempt)) {
// Clear any remaining timers if successful
retryTimers.forEach(t => clearTimeout(t));
}
}, delay);
retryTimers.push(timer);
retryAttempt++;
}
// Return cleanup function to clear all timers
return () => retryTimers.forEach(timer => clearTimeout(timer));
}
}
}
}, [ndk, db]);
// Load relays when NDK is initialized and network is available
2025-03-09 11:15:28 -04:00
useEffect(() => {
if (ndk && isOnline) {
console.log('[RelayInitializer] NDK available and online, loading relays...');
2025-03-09 11:15:28 -04:00
loadRelays().catch(error =>
console.error('[RelayInitializer] Error loading relays:', error)
);
} else if (ndk) {
console.log('[RelayInitializer] NDK available but offline, skipping relay loading');
2025-03-09 11:15:28 -04:00
}
}, [ndk, isOnline]);
// Register for connectivity restoration events
useEffect(() => {
if (!ndk) return;
// Add sync listener to retry when connectivity is restored
const removeListener = ConnectivityService.getInstance().addSyncListener(() => {
if (ndk) {
console.log('[RelayInitializer] Network connectivity restored, attempting to load relays');
loadRelays().catch(error =>
console.error('[RelayInitializer] Error loading relays on reconnect:', error)
);
}
});
return removeListener;
}, [ndk, loadRelays]);
2025-03-09 11:15:28 -04:00
// This component doesn't render anything
return null;
}