import { useState, useEffect } from 'react' import { nostrAuthService } from '@/lib/nostrAuth' import { syncUserContentToCache, type SyncProgress } from '@/lib/userContentSync' import { getLastSyncDate, setLastSyncDate as setLastSyncDateStorage, getCurrentTimestamp, calculateDaysBetween } from '@/lib/syncStorage' import { MIN_EVENT_DATE } from '@/lib/platformConfig' import { objectCache } from '@/lib/objectCache' import { t } from '@/lib/i18n' export function SyncProgressBar(): React.ReactElement | null { console.log('[SyncProgressBar] Component function called') const [syncProgress, setSyncProgress] = useState(null) const [isSyncing, setIsSyncing] = useState(false) const [lastSyncDate, setLastSyncDate] = useState(null) const [totalDays, setTotalDays] = useState(0) const [isInitialized, setIsInitialized] = useState(false) const [connectionState, setConnectionState] = useState<{ connected: boolean; pubkey: string | null }>({ connected: false, pubkey: null }) const [error, setError] = useState(null) async function loadSyncStatus(): Promise { try { const state = nostrAuthService.getState() if (!state.connected || !state.pubkey) { return } const storedLastSyncDate = await getLastSyncDate() const currentTimestamp = getCurrentTimestamp() const days = calculateDaysBetween(storedLastSyncDate, currentTimestamp) setLastSyncDate(storedLastSyncDate) setTotalDays(days) } catch (loadError) { console.error('Error loading sync status:', loadError) } } useEffect(() => { // Check connection state const checkConnection = (): void => { const state = nostrAuthService.getState() console.log('[SyncProgressBar] Initial connection check:', { connected: state.connected, pubkey: state.pubkey }) setConnectionState({ connected: state.connected ?? false, pubkey: state.pubkey ?? null }) setIsInitialized(true) } // Initial check checkConnection() // Listen to connection changes const unsubscribe = nostrAuthService.subscribe((state) => { console.log('[SyncProgressBar] Connection state changed:', { connected: state.connected, pubkey: state.pubkey }) setConnectionState({ connected: state.connected ?? false, pubkey: state.pubkey ?? null }) }) return () => { unsubscribe() } }, []) useEffect(() => { console.log('[SyncProgressBar] Effect triggered:', { isInitialized, connected: connectionState.connected, pubkey: connectionState.pubkey, isSyncing }) if (!isInitialized) { console.log('[SyncProgressBar] Not initialized yet') return } if (!connectionState.connected) { console.log('[SyncProgressBar] Not connected') return } if (!connectionState.pubkey) { console.log('[SyncProgressBar] No pubkey') return } void (async () => { console.log('[SyncProgressBar] Starting sync check...') await loadSyncStatus() // Auto-start sync if not recently synced const storedLastSyncDate = await getLastSyncDate() const currentTimestamp = getCurrentTimestamp() const isRecentlySynced = storedLastSyncDate >= currentTimestamp - 3600 console.log('[SyncProgressBar] Sync status:', { storedLastSyncDate, currentTimestamp, isRecentlySynced, isSyncing }) // Only auto-start if not recently synced if (!isRecentlySynced && !isSyncing && connectionState.pubkey) { console.log('[SyncProgressBar] Starting auto-sync...') setIsSyncing(true) setSyncProgress({ currentStep: 0, totalSteps: 6, completed: false }) try { await syncUserContentToCache(connectionState.pubkey, (progress) => { setSyncProgress(progress) if (progress.completed) { setIsSyncing(false) void loadSyncStatus() } }) // Check if sync completed successfully (if it didn't, isSyncing should still be false) setIsSyncing(false) } catch (autoSyncError) { console.error('[SyncProgressBar] Error during auto-sync:', autoSyncError) setIsSyncing(false) setError(autoSyncError instanceof Error ? autoSyncError.message : 'Erreur de synchronisation') } } else { console.log('[SyncProgressBar] Skipping auto-sync:', { isRecentlySynced, isSyncing, hasPubkey: Boolean(connectionState.pubkey) }) } })() }, [isInitialized, connectionState.connected, connectionState.pubkey, isSyncing]) async function resynchronize(): Promise { try { const state = nostrAuthService.getState() if (!state.connected || !state.pubkey) { return } setIsSyncing(true) setSyncProgress({ currentStep: 0, totalSteps: 6, completed: false }) // Clear cache for user content (but keep other data) await Promise.all([ objectCache.clear('author'), objectCache.clear('series'), objectCache.clear('publication'), objectCache.clear('review'), objectCache.clear('purchase'), objectCache.clear('sponsoring'), objectCache.clear('review_tip'), ]) // Reset last sync date to force full resync await setLastSyncDateStorage(MIN_EVENT_DATE) // Reload sync status await loadSyncStatus() // Start full resynchronization if (state.pubkey !== null) { await syncUserContentToCache(state.pubkey, (progress) => { setSyncProgress(progress) if (progress.completed) { setIsSyncing(false) void loadSyncStatus() } }) } } catch (resyncError) { console.error('Error resynchronizing:', resyncError) setIsSyncing(false) } } // Don't show if not initialized or not connected if (!isInitialized || !connectionState.connected || !connectionState.pubkey) { console.log('[SyncProgressBar] Not rendering:', { isInitialized, connected: connectionState.connected, pubkey: connectionState.pubkey }) return null } console.log('[SyncProgressBar] Rendering component') // Check if sync is recently completed (within last hour) const isRecentlySynced = lastSyncDate !== null && lastSyncDate >= getCurrentTimestamp() - 3600 const progressPercentage = syncProgress && syncProgress.totalSteps > 0 ? Math.min(100, (syncProgress.currentStep / syncProgress.totalSteps) * 100) : 0 const formatDate = (timestamp: number): string => { const date = new Date(timestamp * 1000) const locale = typeof window !== 'undefined' ? navigator.language : 'fr-FR' return date.toLocaleDateString(locale, { day: '2-digit', month: '2-digit', year: 'numeric' }) } const getStartDate = (): number => { if (lastSyncDate !== null) { return lastSyncDate } return MIN_EVENT_DATE } const startDate = getStartDate() const endDate = getCurrentTimestamp() return (
{error && (
{error}
)}

{t('settings.sync.title')}

{!isSyncing && ( )}
{totalDays > 0 && (

{t('settings.sync.daysRange', { startDate: formatDate(startDate), endDate: formatDate(endDate), days: totalDays, })}

)} {isSyncing && syncProgress && (
{t('settings.sync.progress', { current: syncProgress.currentStep, total: syncProgress.totalSteps, })} {Math.round(progressPercentage)}%
)} {!isSyncing && totalDays === 0 && isRecentlySynced && (

{t('settings.sync.completed')}

)} {!isSyncing && totalDays === 0 && !isRecentlySynced && (

{t('settings.sync.ready')}

)}
) }