import { useCallback, useState } from 'react'; import Constants from 'expo-constants'; import { supabase } from '../lib/supabase'; import { protection } from '../lib/protection'; type SyncResult = { ok: boolean; count?: number; plan?: string; error?: string }; /** * Synct die binary Blocklist (`blocklist.bin`) vom Server in die App-Group. * Die NEFilter-Extension memory-mapped diese Datei — ohne Sync = leere * Blocklist = nichts wird geblockt. * * Triggers: * - direkt nach activateUrlFilter() success * - nach Domain-Add/-Submit/-Delete * - bei App-Resume (in case Server-Updates kamen) * * Backend respondet 304 wenn ETag matched → kein Re-Download. */ export function useBlocklistSync() { const [syncing, setSyncing] = useState(false); const [lastResult, setLastResult] = useState(null); const sync = useCallback(async (): Promise => { if (syncing) return { ok: false, error: 'already_syncing' }; setSyncing(true); try { const baseURL = Constants.expoConfig?.extra?.apiUrl as string; const session = (await supabase.auth.getSession()).data.session; const authToken = session?.access_token; if (!baseURL || !authToken) { const result = { ok: false, error: 'missing_baseURL_or_token' }; setLastResult(result); return result; } const res = await protection.syncBlocklist({ baseURL, authToken }); const result = { ok: true, count: res.count, plan: res.plan }; setLastResult(result); console.log('[blocklist-sync] ok:', res); return result; } catch (e: any) { const result = { ok: false, error: e?.message ?? 'sync_failed' }; setLastResult(result); console.error('[blocklist-sync] failed:', e); return result; } finally { setSyncing(false); } }, [syncing]); return { sync, syncing, lastResult }; }