import { useState } from 'react'; import { Linking, Text, TouchableOpacity, View } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { useTranslation } from 'react-i18next'; import { useColors } from '../lib/theme'; import { FormSheet } from './FormSheet'; /** * iOS-spezifischer Recovery-Sheet wenn NEFilter-Aktivierung mit * NEFilterErrorDomain code 5 (Permission denied) fehlschlägt. * * iOS cached "Refuser" einmalig — der System-Dialog kommt beim normalen * activateUrlFilter nicht mehr. Sheet bietet zwei Recovery-Pfade: * 1. „Erneut versuchen" → ruft protection.resetUrlFilter() (Swift macht * removeFromPreferences + frisches saveToPreferences → meist frischer Dialog) * 2. „Einstellungen öffnen" → Deep-Link via Linking.openURL('app-settings:') * wenn auch Reset nicht hilft (z.B. Screen-Time-Restrictions) * * Plus ein 3-Step-Fallback-Hinweis für den Härtefall (App neu installieren). */ export function PermissionDeniedSheet({ visible, onClose, onRetry, }: { visible: boolean; onClose: () => void; /** wird aufgerufen wenn User „Erneut versuchen" tappt — soll protection.resetUrlFilter() callen */ onRetry: () => Promise<{ enabled: boolean; error?: string }>; }) { const colors = useColors(); const { t } = useTranslation(); const [retrying, setRetrying] = useState(false); async function handleRetry() { if (retrying) return; setRetrying(true); try { const res = await onRetry(); if (res.enabled) { // Erfolg — Sheet kann schließen, Outer-Page refresht den Status selbst. onClose(); } // Bei error: Sheet bleibt offen, User kann „Einstellungen öffnen" oder erneut versuchen. } finally { setRetrying(false); } } function openSettings() { Linking.openURL('app-settings:').catch(() => {}); } return ( {/* Icon-Header */} {/* Body */} {t('blocker.permission_denied.body')} {/* Primary Retry */} {retrying ? t('blocker.permission_denied.retry_loading') : t('blocker.permission_denied.retry_cta')} {/* Secondary Settings */} {t('blocker.permission_denied.settings_cta')} {/* Fallback-Hinweis */} {t('blocker.permission_denied.fallback_label')} {t('blocker.permission_denied.fallback_body')} ); }