fix(blocker): webContent-Sync von URL-Filter entkoppeln
syncWebContentDomains war als Side-Effect an syncBlocklist gehaengt, das nur bei aktivem URL-Filter laeuft. Layer 2 haengt aber an Family Controls — der Sync lief nie wenn nur App-Lock/FC aktiv war. Jetzt eigene syncWebContent- Funktion, ungated: Mount + App-Foreground + nach Domain-Add/-Remove. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
bc65c7172c
commit
c3390a0fed
@ -52,7 +52,7 @@ export default function BlockerScreen() {
|
||||
removeDomain,
|
||||
refresh: refreshDomains,
|
||||
} = useCustomDomains(plan);
|
||||
const { sync: syncBlocklist } = useBlocklistSync();
|
||||
const { sync: syncBlocklist, syncWebContent } = useBlocklistSync();
|
||||
|
||||
// Realtime: Domain-Submission-Status (approved/rejected/in_review) live patchen.
|
||||
const onDomainChange = useCallback(async () => {
|
||||
@ -102,13 +102,25 @@ export default function BlockerScreen() {
|
||||
});
|
||||
}, [urlFilterActive, syncBlocklist, refresh]);
|
||||
|
||||
// Layer 2 / VIP: webContent-Domain-Liste IMMER beim Mount syncen — ungated,
|
||||
// da Layer 2 an Family Controls hängt, nicht am URL-Filter.
|
||||
const webContentSyncedRef = useRef(false);
|
||||
useEffect(() => {
|
||||
if (webContentSyncedRef.current) return;
|
||||
webContentSyncedRef.current = true;
|
||||
syncWebContent();
|
||||
}, [syncWebContent]);
|
||||
|
||||
// Wenn User aus System-Settings zurückkommt (z.B. nach a11y-Aktivierung) → State neu laden.
|
||||
useEffect(() => {
|
||||
const sub = AppState.addEventListener('change', (next) => {
|
||||
if (next === 'active') refresh();
|
||||
if (next === 'active') {
|
||||
refresh();
|
||||
syncWebContent();
|
||||
}
|
||||
});
|
||||
return () => sub.remove();
|
||||
}, [refresh]);
|
||||
}, [refresh, syncWebContent]);
|
||||
|
||||
// ─── Activate-Handler pro Layer ──────────────────────────────────────
|
||||
|
||||
@ -224,6 +236,7 @@ export default function BlockerScreen() {
|
||||
async function handleRemoveWebDomain(id: string) {
|
||||
const result = await removeDomain(id);
|
||||
if (result.ok) {
|
||||
syncWebContent();
|
||||
const sync = await syncBlocklist();
|
||||
if (sync.ok) refresh();
|
||||
}
|
||||
@ -388,6 +401,7 @@ export default function BlockerScreen() {
|
||||
onAdd={async (pattern, kind) => {
|
||||
const result = await addDomain(pattern, kind);
|
||||
if (result.ok) {
|
||||
syncWebContent();
|
||||
const sync = await syncBlocklist();
|
||||
if (sync.ok) refresh();
|
||||
}
|
||||
|
||||
@ -18,17 +18,39 @@ type SyncResult = { ok: boolean; count?: number; plan?: string; error?: string }
|
||||
*
|
||||
* Backend respondet 304 wenn ETag matched → kein Re-Download.
|
||||
*
|
||||
* iOS-Layer-2: am selben Trigger wird auch die kuratierte webContent-Gambling-
|
||||
* Domain-Liste vom Backend gesynct (`syncWebContentDomains` →
|
||||
* `webcontent-domains.json` im App-Group-Cache). Best-effort und entkoppelt:
|
||||
* solange der Layer-2-Endpoint nicht deployed ist, schlägt dieser Sync fehl —
|
||||
* das beeinflusst das Blocklist-Sync-Ergebnis NICHT (der native
|
||||
* loadWebContentDomains fällt sauber auf die gebündelte JSON zurück).
|
||||
* iOS-Layer-2 / VIP: die kuratierte webContent-Domain-Liste wird über die
|
||||
* SEPARATE `syncWebContent`-Funktion gesynct — bewusst NICHT an `sync()`
|
||||
* gekoppelt. Layer 2 hängt an Family Controls, nicht am URL-Filter; der Sync
|
||||
* muss daher ungated laufen (auch wenn der URL-Filter aus ist).
|
||||
*/
|
||||
export function useBlocklistSync() {
|
||||
const [syncing, setSyncing] = useState(false);
|
||||
const [lastResult, setLastResult] = useState<SyncResult | null>(null);
|
||||
|
||||
// iOS-Layer-2 / VIP-Liste: kuratierte webContent-Domain-Liste vom Backend
|
||||
// syncen. ENTKOPPELT vom Blocklist-Sync — Layer 2 hängt an Family Controls,
|
||||
// NICHT am URL-Filter, also ungated aufrufbar. Best-effort: schlägt es fehl,
|
||||
// greift nativ der gebündelte Fallback (loadWebContentDomains).
|
||||
const syncWebContent = useCallback(async (): Promise<void> => {
|
||||
if (Platform.OS !== 'ios') return;
|
||||
const baseURL = Constants.expoConfig?.extra?.apiUrl as string;
|
||||
const session = (await supabase.auth.getSession()).data.session;
|
||||
const authToken = session?.access_token;
|
||||
if (!baseURL || !authToken) {
|
||||
console.warn('[webcontent-sync] skipped — missing baseURL/token');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await protection.syncWebContentDomains({ baseURL, authToken });
|
||||
console.log('[webcontent-sync] ok:', JSON.stringify(res));
|
||||
} catch (e: any) {
|
||||
console.warn(
|
||||
'[webcontent-sync] failed (bundled fallback active):',
|
||||
e?.message ?? e,
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const sync = useCallback(async (): Promise<SyncResult> => {
|
||||
if (syncing) return { ok: false, error: 'already_syncing' };
|
||||
setSyncing(true);
|
||||
@ -43,24 +65,6 @@ export function useBlocklistSync() {
|
||||
return result;
|
||||
}
|
||||
|
||||
// iOS-Layer-2: webContent-Domain-Liste am selben Trigger mitsyncen.
|
||||
// Bewusst NICHT awaited mit dem Blocklist-Sync gekoppelt — ein
|
||||
// Fehlschlag (z.B. Endpoint noch nicht deployed) darf das Blocklist-
|
||||
// Ergebnis nicht kippen. Fallback auf die gebündelte JSON greift nativ.
|
||||
if (Platform.OS === 'ios') {
|
||||
protection
|
||||
.syncWebContentDomains({ baseURL, authToken })
|
||||
.then((res) =>
|
||||
console.log('[webcontent-sync] ok:', JSON.stringify(res)),
|
||||
)
|
||||
.catch((e: any) =>
|
||||
console.warn(
|
||||
'[webcontent-sync] failed (bundled fallback active):',
|
||||
e?.message ?? e,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const res = await protection.syncBlocklist({ baseURL, authToken });
|
||||
const result = { ok: true, count: res.count, plan: res.plan };
|
||||
setLastResult(result);
|
||||
@ -76,5 +80,5 @@ export function useBlocklistSync() {
|
||||
}
|
||||
}, [syncing]);
|
||||
|
||||
return { sync, syncing, lastResult };
|
||||
return { sync, syncWebContent, syncing, lastResult };
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user